From lattner at cs.uiuc.edu Mon Apr 12 00:16:11 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:16:11 2004
Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/GCSE.cpp
Message-ID: <200404120515.AAA27695@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/Scalar:
GCSE.cpp updated: 1.38 -> 1.39
---
Log message:
Add support for removing invoke instructions
---
Diffs of the changes: (+14 -0)
Index: llvm/lib/Transforms/Scalar/GCSE.cpp
diff -u llvm/lib/Transforms/Scalar/GCSE.cpp:1.38 llvm/lib/Transforms/Scalar/GCSE.cpp:1.39
--- llvm/lib/Transforms/Scalar/GCSE.cpp:1.38 Sat Apr 10 17:33:34 2004
+++ llvm/lib/Transforms/Scalar/GCSE.cpp Mon Apr 12 00:15:13 2004
@@ -167,6 +167,13 @@
// anything special.
if (!isa(V)) {
I->replaceAllUsesWith(V);
+
+ if (InvokeInst *II = dyn_cast(I)) {
+ // Removing an invoke instruction requires adding a branch to the normal
+ // destination and removing PHI node entries in the exception destination.
+ new BranchInst(II->getNormalDest(), II);
+ II->getUnwindDest()->removePredecessor(II->getParent());
+ }
// Erase the instruction from the program.
I->getParent()->getInstList().erase(I);
@@ -178,6 +185,13 @@
// Perform the replacement.
I->replaceAllUsesWith(C);
+
+ if (InvokeInst *II = dyn_cast(I)) {
+ // Removing an invoke instruction requires adding a branch to the normal
+ // destination and removing PHI node entries in the exception destination.
+ new BranchInst(II->getNormalDest(), II);
+ II->getUnwindDest()->removePredecessor(II->getParent());
+ }
// Erase the instruction from the program.
I->getParent()->getInstList().erase(I);
From lattner at cs.uiuc.edu Mon Apr 12 00:17:01 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:17:01 2004
Subject: [llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp
Message-ID: <200404120516.AAA28188@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Analysis:
BasicAliasAnalysis.cpp updated: 1.39 -> 1.40
---
Log message:
Hrm, operator new and new[] do not belong here. We should not CSE them! :)
---
Diffs of the changes: (+0 -3)
Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff -u llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.39 llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.40
--- llvm/lib/Analysis/BasicAliasAnalysis.cpp:1.39 Sun Apr 11 13:16:34 2004
+++ llvm/lib/Analysis/BasicAliasAnalysis.cpp Mon Apr 12 00:16:42 2004
@@ -646,9 +646,6 @@
// glibc functions:
"__fpclassify", "__fpclassifyf", "__fpclassifyl",
"__signbit", "__signbitf", "__signbitl",
-
- // C++ operator new/operator new[]
- "_Znwj", "_Znaj",
};
static const unsigned DAMTableSize =
From lattner at cs.uiuc.edu Mon Apr 12 00:37:01 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:37:01 2004
Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/CallGraph.h
Message-ID: <200404120536.AAA29845@zion.cs.uiuc.edu>
Changes in directory llvm/include/llvm/Analysis:
CallGraph.h updated: 1.33 -> 1.34
---
Log message:
Change the call graph class to have TWO external nodes, making call graph
SCC passes much more useful. In particular, this should fix the incredibly
stupid missed inlining opportunities that the inliner suffered from.
---
Diffs of the changes: (+35 -24)
Index: llvm/include/llvm/Analysis/CallGraph.h
diff -u llvm/include/llvm/Analysis/CallGraph.h:1.33 llvm/include/llvm/Analysis/CallGraph.h:1.34
--- llvm/include/llvm/Analysis/CallGraph.h:1.33 Tue Nov 11 16:41:30 2003
+++ llvm/include/llvm/Analysis/CallGraph.h Mon Apr 12 00:36:22 2004
@@ -14,17 +14,20 @@
// callgraph node keeps track of which functions the are called by the function
// corresponding to the node.
//
-// A call graph will contain nodes where the function that they correspond to is
-// null. This 'external' node is used to represent control flow that is not
-// represented (or analyzable) in the module. As such, the external node will
-// have edges to functions with the following properties:
-// 1. All functions in the module without internal linkage, since they could
-// be called by functions outside of the our analysis capability.
+// A call graph may contain nodes where the function that they correspond to is
+// null. These 'external' nodes are used to represent control flow that is not
+// represented (or analyzable) in the module. In particular, this analysis
+// builds one external node such that:
+// 1. All functions in the module without internal linkage will have edges
+// from this external node, indicating that they could be called by
+// functions outside of the module.
// 2. All functions whose address is used for something more than a direct
-// call, for example being stored into a memory location. Since they may
-// be called by an unknown caller later, they must be tracked as such.
+// call, for example being stored into a memory location will also have an
+// edge from this external node. Since they may be called by an unknown
+// caller later, they must be tracked as such.
//
-// Similarly, functions have a call edge to the external node iff:
+// There is a second external node added for calls that leave this module.
+// Functions have a call edge to the external node iff:
// 1. The function is external, reflecting the fact that they could call
// anything without internal linkage or that has its address taken.
// 2. The function contains an indirect function call.
@@ -68,9 +71,18 @@
FunctionMapTy FunctionMap; // Map from a function to its node
// Root is root of the call graph, or the external node if a 'main' function
- // couldn't be found. ExternalNode is equivalent to (*this)[0].
+ // couldn't be found.
//
- CallGraphNode *Root, *ExternalNode;
+ CallGraphNode *Root;
+
+ // ExternalCallingNode - This node has edges to all external functions and
+ // those internal functions that have their address taken.
+ CallGraphNode *ExternalCallingNode;
+
+ // CallsExternalNode - This node has edges to it from all functions making
+ // indirect calls or calling an external function.
+ CallGraphNode *CallsExternalNode;
+
public:
//===---------------------------------------------------------------------
@@ -79,11 +91,8 @@
typedef FunctionMapTy::iterator iterator;
typedef FunctionMapTy::const_iterator const_iterator;
- // getExternalNode - Return the node that points to all functions that are
- // accessable from outside of the current program.
- //
- CallGraphNode *getExternalNode() { return ExternalNode; }
- const CallGraphNode *getExternalNode() const { return ExternalNode; }
+ CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; }
+ CallGraphNode *getCallsExternalNode() const { return CallsExternalNode; }
// getRoot - Return the root of the call graph, which is either main, or if
// main cannot be found, the external node.
@@ -215,17 +224,19 @@
CalledFunctions.clear();
}
-private: // Stuff to construct the node, used by CallGraph
- friend class CallGraph;
-
- // CallGraphNode ctor - Create a node for the specified function...
- inline CallGraphNode(Function *f) : F(f) {}
-
// addCalledFunction add a function to the list of functions called by this
// one
void addCalledFunction(CallGraphNode *M) {
CalledFunctions.push_back(M);
}
+
+ void removeCallEdgeTo(CallGraphNode *Callee);
+
+private: // Stuff to construct the node, used by CallGraph
+ friend class CallGraph;
+
+ // CallGraphNode ctor - Create a node for the specified function...
+ inline CallGraphNode(Function *f) : F(f) {}
};
@@ -257,7 +268,7 @@
template<> struct GraphTraits : public GraphTraits {
static NodeType *getEntryNode(CallGraph *CGN) {
- return CGN->getExternalNode(); // Start at the external node!
+ return CGN->getExternalCallingNode(); // Start at the external node!
}
typedef std::pair PairTy;
typedef std::pointer_to_unary_function DerefFun;
@@ -279,7 +290,7 @@
template<> struct GraphTraits :
public GraphTraits {
static NodeType *getEntryNode(const CallGraph *CGN) {
- return CGN->getExternalNode();
+ return CGN->getExternalCallingNode();
}
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef CallGraph::const_iterator nodes_iterator;
From lattner at cs.uiuc.edu Mon Apr 12 00:37:04 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:37:04 2004
Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/CallGraph.cpp
Message-ID: <200404120536.AAA29858@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Analysis/IPA:
CallGraph.cpp updated: 1.34 -> 1.35
---
Log message:
Change the call graph class to have TWO external nodes, making call graph
SCC passes much more useful. In particular, this should fix the incredibly
stupid missed inlining opportunities that the inliner suffered from.
---
Diffs of the changes: (+22 -181)
Index: llvm/lib/Analysis/IPA/CallGraph.cpp
diff -u llvm/lib/Analysis/IPA/CallGraph.cpp:1.34 llvm/lib/Analysis/IPA/CallGraph.cpp:1.35
--- llvm/lib/Analysis/IPA/CallGraph.cpp:1.34 Tue Nov 11 16:41:32 2003
+++ llvm/lib/Analysis/IPA/CallGraph.cpp Mon Apr 12 00:36:32 2004
@@ -7,41 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This interface is used to build and manipulate a call graph, which is a very
-// useful tool for interprocedural optimization.
-//
-// Every function in a module is represented as a node in the call graph. The
-// callgraph node keeps track of which functions the are called by the function
-// corresponding to the node.
-//
-// A call graph will contain nodes where the function that they correspond to is
-// null. This 'external' node is used to represent control flow that is not
-// represented (or analyzable) in the module. As such, the external node will
-// have edges to functions with the following properties:
-// 1. All functions in the module without internal linkage, since they could
-// be called by functions outside of the our analysis capability.
-// 2. All functions whose address is used for something more than a direct
-// call, for example being stored into a memory location. Since they may
-// be called by an unknown caller later, they must be tracked as such.
-//
-// Similarly, functions have a call edge to the external node iff:
-// 1. The function is external, reflecting the fact that they could call
-// anything without internal linkage or that has its address taken.
-// 2. The function contains an indirect function call.
-//
-// As an extension in the future, there may be multiple nodes with a null
-// function. These will be used when we can prove (through pointer analysis)
-// that an indirect call site can call only a specific set of functions.
-//
-// Because of these properties, the CallGraph captures a conservative superset
-// of all of the caller-callee relationships, which is useful for
-// transformations.
-//
-// The CallGraph class also attempts to figure out what the root of the
-// CallGraph is, which is currently does by looking for a function named 'main'.
-// If no function named 'main' is found, the external node is used as the entry
-// node, reflecting the fact that any function without internal linkage could
-// be called into (which is common for libraries).
+// This file implements the CallGraph class.
//
//===----------------------------------------------------------------------===//
@@ -52,143 +18,10 @@
#include "llvm/iTerminators.h"
#include "llvm/Support/CallSite.h"
#include "Support/STLExtras.h"
-
-namespace llvm {
+using namespace llvm;
static RegisterAnalysis X("callgraph", "Call Graph Construction");
-static const char * const KnownExternalFunctions[] = {
- // Low-level system calls
- "open",
- "read",
- "write",
- "writev",
- "lseek",
- "poll",
- "ioctl",
-
- // Low-level stdc library functions
- "abort", "exit",
- "getenv", "putenv",
-
- // Standard IO functions
- "printf",
- "sprintf",
- "fopen",
- "freopen",
- "fclose",
- "fwrite",
- "puts",
- "fputs",
- "getc",
- "ungetc",
- "putc",
- "putchar",
- "fread",
- "fileno",
- "ftell",
- "fflush",
- "fseek",
- "fileno",
- "ferror",
- "feof",
- "fdopen",
- "__fxstat",
- "setbuf",
- "setbuffer",
- "etlinebuf",
- "setvbuf",
-
- // Memory functions
- "malloc",
- "free",
- "realloc",
- "calloc",
- "memalign",
-
- // String functions
- "atoi",
- "memmove",
- "memset",
- "memchr",
- "memcmp",
- "strchr",
- "strncpy",
- "strncmp",
- "strcmp",
- "strtok",
- "__strcoll_l",
- "__strxfrm_l",
- "__strftime_l",
- "__strtol_l",
- "__strtoul_l",
- "__strtoll_l",
- "__strtoull_l",
- "__strtof_l",
- "__strtod_l",
- "__strtold_l",
- "isalpha",
-
- // Math functions
- "exp", "sqrt", "cbrt", "hypot",
- "log", "log10", "pow",
- "sin", "cos", "tan",
- "asin", "acos", "atan", "atan2",
-
- // Locale functions
- "__uselocale",
- "__newlocale",
- "__freelocale",
- "__duplocale",
- "__nl_langinfo_l",
-
- // gettext functions used by libstdc++
- "gettext",
- "dgettext",
- "dcgettext",
- "textdomain",
- "bindtextdomain",
-
- // Random stuff
- "__assert_fail",
- "__errno_location",
- "clock", "time",
- "__main",
-};
-
-
-/// ExternalFunctionDoesntCallIntoProgram - This hack is used to indicate to the
-/// call graph that the specified external function is _KNOWN_ to not call back
-/// into the program. This is important, because otherwise functions which call
-/// "printf" for example, end up in a great big SCC that goes from the function
-/// through main.
-///
-static bool ExternalFunctionDoesntCallIntoProgram(const std::string &Name) {
- static std::vector Funcs;
-
- // First time this is called?
- if (Funcs.empty()) {
- // Add a whole bunch of functions which are often used...
- Funcs.insert(Funcs.end(), KnownExternalFunctions,
- KnownExternalFunctions+
- sizeof(KnownExternalFunctions)/sizeof(KnownExternalFunctions[0]));
- // Sort the list for efficient access
- std::sort(Funcs.begin(), Funcs.end());
- }
-
- if (Name.size() > 7 && !memcmp("__llvm_", Name.c_str(), 7))
- return true;
-
- // Binary search for the function name...
- std::vector::iterator I =
- std::lower_bound(Funcs.begin(), Funcs.end(), Name);
-
- // Found it?
- return I != Funcs.end() && *I == Name;
-}
-
-
-
// getNodeFor - Return the node for the specified function or create one if it
// does not already exist.
//
@@ -215,12 +48,12 @@
// If this function has external linkage, anything could call it...
if (!F->hasInternalLinkage()) {
- ExternalNode->addCalledFunction(Node);
+ ExternalCallingNode->addCalledFunction(Node);
// Found the entry point?
if (F->getName() == "main") {
- if (Root)
- Root = ExternalNode; // Found multiple external mains? Don't pick one.
+ if (Root) // Found multiple external mains? Don't pick one.
+ Root = ExternalCallingNode;
else
Root = Node; // Found a main, keep track of it!
}
@@ -228,9 +61,8 @@
// If this function is not defined in this translation unit, it could call
// anything.
- if (F->isExternal() && !F->getIntrinsicID() &&
- !ExternalFunctionDoesntCallIntoProgram(F->getName()))
- Node->addCalledFunction(ExternalNode);
+ if (F->isExternal() && !F->getIntrinsicID())
+ Node->addCalledFunction(CallsExternalNode);
// Loop over all of the users of the function... looking for callers...
//
@@ -259,14 +91,14 @@
}
}
if (isUsedExternally)
- ExternalNode->addCalledFunction(Node);
+ ExternalCallingNode->addCalledFunction(Node);
// Look for an indirect function call...
for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB)
for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II){
CallSite CS = CallSite::get(II);
if (CS.getInstruction() && !CS.getCalledFunction())
- Node->addCalledFunction(ExternalNode);
+ Node->addCalledFunction(CallsExternalNode);
}
}
@@ -274,7 +106,8 @@
destroy();
Mod = &M;
- ExternalNode = getNodeFor(0);
+ ExternalCallingNode = getNodeFor(0);
+ CallsExternalNode = new CallGraphNode(0);
Root = 0;
// Add every function to the call graph...
@@ -282,7 +115,7 @@
addToCallGraph(I);
// If we didn't find a main function, use the external call graph node
- if (Root == 0) Root = ExternalNode;
+ if (Root == 0) Root = ExternalCallingNode;
return false;
}
@@ -328,7 +161,7 @@
// Functions to keep a call graph up to date with a function that has been
// modified
//
-void CallGraph::addFunctionToModule(Function *Meth) {
+void CallGraph::addFunctionToModule(Function *F) {
assert(0 && "not implemented");
abort();
}
@@ -352,4 +185,12 @@
void CallGraph::stub() {}
-} // End llvm namespace
+void CallGraphNode::removeCallEdgeTo(CallGraphNode *Callee) {
+ for (unsigned i = CalledFunctions.size(); ; --i) {
+ assert(i && "Cannot find callee to remove!");
+ if (CalledFunctions[i-1] == Callee) {
+ CalledFunctions.erase(CalledFunctions.begin()+i-1);
+ return;
+ }
+ }
+}
From lattner at cs.uiuc.edu Mon Apr 12 00:38:01 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:38:01 2004
Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/Inliner.cpp
Message-ID: <200404120537.AAA30010@zion.cs.uiuc.edu>
Changes in directory llvm/lib/Transforms/IPO:
Inliner.cpp updated: 1.8 -> 1.9
---
Log message:
Actually update the call graph as the inliner changes it. This allows us to
execute other CallGraphSCCPasses after the inliner without crashing.
---
Diffs of the changes: (+20 -1)
Index: llvm/lib/Transforms/IPO/Inliner.cpp
diff -u llvm/lib/Transforms/IPO/Inliner.cpp:1.8 llvm/lib/Transforms/IPO/Inliner.cpp:1.9
--- llvm/lib/Transforms/IPO/Inliner.cpp:1.8 Sun Apr 11 23:06:56 2004
+++ llvm/lib/Transforms/IPO/Inliner.cpp Mon Apr 12 00:37:29 2004
@@ -93,7 +93,21 @@
// Attempt to inline the function...
if (InlineFunction(CS)) {
++NumInlined;
+
+ // Update the call graph by deleting the edge from Callee to Caller
+ CallGraphNode *CalleeNode = CG[Callee];
+ CallGraphNode *CallerNode = CG[Caller];
+ CallerNode->removeCallEdgeTo(CalleeNode);
+
+ // Since we inlined all uninlinable call sites in the callee into the
+ // caller, add edges from the caller to all of the callees of the
+ // callee.
+ for (CallGraphNode::iterator I = CalleeNode->begin(),
+ E = CalleeNode->end(); I != E; ++I)
+ CallerNode->addCalledFunction(*I);
+ // If the only remaining use of the function is a dead constant
+ // pointer ref, remove it.
if (Callee->hasOneUse())
if (ConstantPointerRef *CPR =
dyn_cast(Callee->use_back()))
@@ -110,7 +124,12 @@
if (I != SCCFunctions.end()) // Remove function from this SCC.
SCCFunctions.erase(I);
- Callee->getParent()->getFunctionList().erase(Callee);
+ // Remove any call graph edges from the callee to its callees.
+ while (CalleeNode->begin() != CalleeNode->end())
+ CalleeNode->removeCallEdgeTo(*(CalleeNode->end()-1));
+
+ // Removing the node for callee from the call graph and delete it.
+ delete CG.removeFunctionFromModule(CalleeNode);
++NumDeleted;
}
Changed = true;
From lattner at cs.uiuc.edu Mon Apr 12 00:38:04 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:38:04 2004
Subject: [llvm-commits] CVS: llvm/tools/analyze/GraphPrinters.cpp
Message-ID: <200404120538.AAA30042@zion.cs.uiuc.edu>
Changes in directory llvm/tools/analyze:
GraphPrinters.cpp updated: 1.6 -> 1.7
---
Log message:
finegrainify namespacification
---
Diffs of the changes: (+16 -17)
Index: llvm/tools/analyze/GraphPrinters.cpp
diff -u llvm/tools/analyze/GraphPrinters.cpp:1.6 llvm/tools/analyze/GraphPrinters.cpp:1.7
--- llvm/tools/analyze/GraphPrinters.cpp:1.6 Tue Nov 11 16:41:34 2003
+++ llvm/tools/analyze/GraphPrinters.cpp Mon Apr 12 00:38:01 2004
@@ -19,8 +19,7 @@
#include "llvm/Value.h"
#include "llvm/Analysis/CallGraph.h"
#include
-
-namespace llvm {
+using namespace llvm;
template
static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
@@ -41,19 +40,21 @@
// Call Graph Printer
//===----------------------------------------------------------------------===//
-template<>
-struct DOTGraphTraits : public DefaultDOTGraphTraits {
- static std::string getGraphName(CallGraph *F) {
- return "Call Graph";
- }
-
- static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) {
- if (Node->getFunction())
- return ((Value*)Node->getFunction())->getName();
- else
- return "Indirect call node";
- }
-};
+namespace llvm {
+ template<>
+ struct DOTGraphTraits : public DefaultDOTGraphTraits {
+ static std::string getGraphName(CallGraph *F) {
+ return "Call Graph";
+ }
+
+ static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) {
+ if (Node->getFunction())
+ return ((Value*)Node->getFunction())->getName();
+ else
+ return "Indirect call node";
+ }
+ };
+}
namespace {
@@ -74,5 +75,3 @@
RegisterAnalysis P2("print-callgraph",
"Print Call Graph to 'dot' file");
};
-
-} // End llvm namespace
From lattner at cs.uiuc.edu Mon Apr 12 00:39:01 2004
From: lattner at cs.uiuc.edu (Chris Lattner)
Date: Mon Apr 12 00:39:01 2004
Subject: [llvm-commits] CVS: llvm/tools/gccld/GenerateCode.cpp
Message-ID: <200404120538.AAA30051@zion.cs.uiuc.edu>
Changes in directory llvm/tools/gccld:
GenerateCode.cpp updated: 1.26 -> 1.27
---
Log message:
Add a couple more IPO's
---
Diffs of the changes: (+3 -0)
Index: llvm/tools/gccld/GenerateCode.cpp
diff -u llvm/tools/gccld/GenerateCode.cpp:1.26 llvm/tools/gccld/GenerateCode.cpp:1.27
--- llvm/tools/gccld/GenerateCode.cpp:1.26 Thu Apr 8 10:18:59 2004
+++ llvm/tools/gccld/GenerateCode.cpp Mon Apr 12 00:38:15 2004
@@ -105,6 +105,9 @@
if (!DisableInline)
addPass(Passes, createFunctionInliningPass()); // Inline small functions
+ addPass(Passes, createPruneEHPass()); // Remove dead EH info
+ addPass(Passes, createGlobalDCEPass()); // Remove dead functions
+
// If we didn't decide to inline a function, check to see if we can
// transform it to pass arguments by value instead of by reference.
addPass(Passes, createArgumentPromotionPass());
From criswell at cs.uiuc.edu Mon Apr 12 10:03:03 2004
From: criswell at cs.uiuc.edu (John Criswell)
Date: Mon Apr 12 10:03:03 2004
Subject: [llvm-commits] CVS: llvm/docs/LangRef.html
Message-ID: <200404121502.KAA22281@choi.cs.uiuc.edu>
Changes in directory llvm/docs:
LangRef.html updated: 1.58 -> 1.59
---
Log message:
Added initial design for the llvm.readio and llvm.writeio intrinsics.
---
Diffs of the changes: (+97 -1)
Index: llvm/docs/LangRef.html
diff -u llvm/docs/LangRef.html:1.58 llvm/docs/LangRef.html:1.59
--- llvm/docs/LangRef.html:1.58 Fri Apr 9 11:48:45 2004
+++ llvm/docs/LangRef.html Mon Apr 12 10:02:16 2004
@@ -107,6 +107,8 @@
- 'llvm.readport' Intrinsic
- 'llvm.writeport' Intrinsic
+ - 'llvm.readio' Intrinsic
+ - 'llvm.writeio' Intrinsic
Standard C Library Intrinsics
@@ -2013,6 +2015,7 @@
+
+
+
+
+
+
+
Syntax:
+
+ call <integer type> (<integer type>)* %llvm.readio (<integer type> <address>)
+
+
+
Overview:
+
+
+The 'llvm.readio' intrinsic reads data from a memory mapped I/O
+address.
+
+
+
Arguments:
+
+
+The argument to this intrinsic indicates the memory address from which to read
+the data.
+
+
+
Semantics:
+
+
+The 'llvm.readio' intrinsic reads data from a memory mapped I/O
+location specified by address and returns the value. The address and
+return value must be integers, but the size allowed for each is dependent upon
+the platform upon which the program is code generated.
+
+
+
+This intrinsic ensures that the I/O data read occurs in instruction order in
+relation to other I/O data reads and writes (as opposed to a normal load, where
+hardware scheduling can re-arrange the actual memory accesses to occur out of
+order).
+
+
+
+
+
+
+
+
+
+
Syntax:
+
+ call void (<integer type>, <integer type>)* %llvm.writeio (<integer type> <value>, <integer type> <address>)
+
+
+
Overview:
+
+
+The 'llvm.writeio' intrinsic writes data to the specified memory
+mapped I/O address.
+
+
+
Arguments:
+
+
+The first argument to this intrinsic indicates the memory address to which data
+should be written.
+
+
+
+The second argument is the value to write to the memory mapped I/O location.
+
+
+
Semantics:
+
+
+The 'llvm.writeio' intrinsic writes value to the memory mapped
+I/O address specified by address. The address and value must be
+integers, but the size is dependent upon the platform upon which the program is
+code generated.
+
+
+
+This intrinsic ensures that the I/O data write occurs in instruction order in
+relation to other I/O data reads and writes (as opposed to a normal store,
+where hardware scheduling can re-arrange the actual memory accesses to occur
+out of order).
+
+
+
+
+