[llvm-commits] CVS: llvm/lib/Target/CBackend/CBackend.cpp
Reid Spencer
reid at x10sys.com
Thu Apr 12 14:01:02 PDT 2007
Changes in directory llvm/lib/Target/CBackend:
CBackend.cpp updated: 1.334 -> 1.335
---
Log message:
Provide support for intrinsics that lower themselves to a function body.
This can happen for intrinsics that are overloaded. In such cases it is
necessary to emit a function prototype before the body of the function
that calls the intrinsic and to ensure we don't emit it multiple times.
---
Diffs of the changes: (+32 -2)
CBackend.cpp | 34 ++++++++++++++++++++++++++++++++--
1 files changed, 32 insertions(+), 2 deletions(-)
Index: llvm/lib/Target/CBackend/CBackend.cpp
diff -u llvm/lib/Target/CBackend/CBackend.cpp:1.334 llvm/lib/Target/CBackend/CBackend.cpp:1.335
--- llvm/lib/Target/CBackend/CBackend.cpp:1.334 Thu Apr 12 13:42:08 2007
+++ llvm/lib/Target/CBackend/CBackend.cpp Thu Apr 12 16:00:45 2007
@@ -45,6 +45,7 @@
#include "llvm/Config/config.h"
#include <algorithm>
#include <sstream>
+// #include <set>
using namespace llvm;
namespace {
@@ -78,8 +79,9 @@
const TargetAsmInfo* TAsm;
const TargetData* TD;
std::map<const Type *, std::string> TypeNames;
-
std::map<const ConstantFP *, unsigned> FPConstantMap;
+ std::set<Function*> intrinsicPrototypesAlreadyGenerated;
+
public:
CWriter(std::ostream &o) : Out(o), IL(0), Mang(0), LI(0), TheModule(0),
TAsm(0), TD(0) {}
@@ -2364,6 +2366,13 @@
void CWriter::lowerIntrinsics(Function &F) {
+ // This is used to keep track of intrinsics that get generated to a lowered
+ // function. We must generate the prototypes before the function body which
+ // will only be expanded on first use (by the loop below).
+ std::vector<Function*> prototypesToGen;
+
+ // Examine all the instructions in this function to find the intrinsics that
+ // need to be lowered.
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
if (CallInst *CI = dyn_cast<CallInst>(I++))
@@ -2404,10 +2413,31 @@
} else {
I = BB->begin();
}
+ // If the intrinsic got lowered to another call, and that call has
+ // a definition then we need to make sure its prototype is emitted
+ // before any calls to it.
+ if (CallInst *Call = dyn_cast<CallInst>(I))
+ if (Function *NewF = Call->getCalledFunction())
+ if (!NewF->isDeclaration())
+ prototypesToGen.push_back(NewF);
+
break;
}
-}
+ // We may have collected some prototypes to emit in the loop above.
+ // Emit them now, before the function that uses them is emitted. But,
+ // be careful not to emit them twice.
+ std::vector<Function*>::iterator I = prototypesToGen.begin();
+ std::vector<Function*>::iterator E = prototypesToGen.end();
+ for ( ; I != E; ++I) {
+ if (intrinsicPrototypesAlreadyGenerated.count(*I) == 0) {
+ Out << '\n';
+ printFunctionSignature(*I, true);
+ Out << ";\n";
+ intrinsicPrototypesAlreadyGenerated.insert(*I);
+ }
+ }
+}
void CWriter::visitCallInst(CallInst &I) {
More information about the llvm-commits
mailing list