[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