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) { _______________________________________________ llvm-commits mailing list [EMAIL PROTECTED] http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits