From 4ef51373c423fc3cff1e72dd08b4256cdc90362a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 14 Feb 2004 00:31:10 +0000 Subject: [PATCH] Use intrinsic lowering like the rest of the backends. Get rid of crufty hacky code that worked around problems in the mangler git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11426 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CBackend/CBackend.cpp | 103 ++++++++++++------------------- lib/Target/CBackend/Writer.cpp | 103 ++++++++++++------------------- 2 files changed, 80 insertions(+), 126 deletions(-) diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 25c940a6e1b..493e7ec5fcc 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -22,6 +22,7 @@ #include "llvm/PassManager.h" #include "llvm/SymbolTable.h" #include "llvm/Intrinsics.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Transforms/Scalar.h" @@ -37,16 +38,16 @@ using namespace llvm; namespace { class CWriter : public Pass, public InstVisitor { std::ostream &Out; + IntrinsicLowering &IL; Mangler *Mang; const Module *TheModule; FindUsedTypes *FUT; std::map TypeNames; - std::set MangledGlobals; std::map FPConstantMap; public: - CWriter(std::ostream &o) : Out(o) {} + CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {} void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -56,6 +57,9 @@ namespace { bool doInitialization(Module &M); bool run(Module &M) { + // First pass, lower all unhandled intrinsics. + lowerIntrinsics(M); + doInitialization(M); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) @@ -65,7 +69,6 @@ namespace { // Free memory... delete Mang; TypeNames.clear(); - MangledGlobals.clear(); return true; } @@ -77,6 +80,8 @@ namespace { void writeOperandInternal(Value *Operand); private : + void lowerIntrinsics(Module &M); + bool nameAllUsedStructureTypes(Module &M); void printModule(Module *M); void printFloatingPointConstants(Module &M); @@ -160,6 +165,7 @@ namespace { void printIndexingExpression(Value *Ptr, gep_type_iterator I, gep_type_iterator E); }; +} // Pass the Type* and the variable name and this prints out the variable // declaration. @@ -612,25 +618,6 @@ bool CWriter::doInitialization(Module &M) { bool Changed = nameAllUsedStructureTypes(M); Mang = new Mangler(M); - // Calculate which global values have names that will collide when we throw - // away type information. - { // Scope to delete the FoundNames set when we are done with it... - std::set FoundNames; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->hasName()) // If the global has a name... - if (FoundNames.count(I->getName())) // And the name is already used - MangledGlobals.insert(I); // Mangle the name - else - FoundNames.insert(I->getName()); // Otherwise, keep track of name - - for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (I->hasName()) // If the global has a name... - if (FoundNames.count(I->getName())) // And the name is already used - MangledGlobals.insert(I); // Mangle the name - else - FoundNames.insert(I->getName()); // Otherwise, keep track of name - } - // get declaration for alloca Out << "/* Provide Declarations */\n"; Out << "#include \n"; // Varargs support @@ -670,11 +657,8 @@ bool CWriter::doInitialization(Module &M) { if (!M.empty()) { Out << "\n/* Function Declarations */\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - // If the function is external and the name collides don't print it. - // Sometimes the bytecode likes to have multiple "declarations" for - // external functions - if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && - !I->getIntrinsicID() && + // Don't print declarations for intrinsic functions. + if (!I->getIntrinsicID() && I->getName() != "setjmp" && I->getName() != "longjmp") { printFunctionSignature(I, true); if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; @@ -1162,12 +1146,39 @@ void CWriter::visitCastInst(CastInst &I) { writeOperand(I.getOperand(0)); } +void CWriter::lowerIntrinsics(Module &M) { + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + 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(I++)) + if (Function *F = CI->getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::not_intrinsic: + case Intrinsic::va_start: + case Intrinsic::va_copy: + case Intrinsic::va_end: + // We directly implement these intrinsics + break; + default: + // All other intrinsic calls we must lower. + Instruction *Before = CI->getPrev(); + IL.LowerIntrinsicCall(CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + } +} + + + void CWriter::visitCallInst(CallInst &I) { // Handle intrinsic function calls first... if (Function *F = I.getCalledFunction()) if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { switch (ID) { - default: assert(0 && "Unknown LLVM intrinsic!"); + default: assert(0 && "Unknown LLVM intrinsic!"); case Intrinsic::va_start: Out << "0; "; @@ -1194,38 +1205,6 @@ void CWriter::visitCallInst(CallInst &I) { writeOperand(I.getOperand(1)); Out << ")"; return; - case Intrinsic::setjmp: - case Intrinsic::sigsetjmp: - // This intrinsic should never exist in the program, but until we get - // setjmp/longjmp transformations going on, we should codegen it to - // something reasonable. This will allow code that never calls longjmp - // to work. - Out << "0"; - return; - case Intrinsic::longjmp: - case Intrinsic::siglongjmp: - // Longjmp is not implemented, and never will be. It would cause an - // exception throw. - Out << "abort()"; - return; - case Intrinsic::memcpy: - Out << "memcpy("; - writeOperand(I.getOperand(1)); - Out << ", "; - writeOperand(I.getOperand(2)); - Out << ", "; - writeOperand(I.getOperand(3)); - Out << ")"; - return; - case Intrinsic::memmove: - Out << "memmove("; - writeOperand(I.getOperand(1)); - Out << ", "; - writeOperand(I.getOperand(2)); - Out << ", "; - writeOperand(I.getOperand(3)); - Out << ")"; - return; } } visitCallSite(&I); @@ -1364,8 +1343,6 @@ void CWriter::visitVAArgInst(VAArgInst &I) { Out << ");\n va_end(Tmp); }"; } -} - //===----------------------------------------------------------------------===// // External Interface declaration //===----------------------------------------------------------------------===// @@ -1373,7 +1350,7 @@ void CWriter::visitVAArgInst(VAArgInst &I) { bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) { PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); - PM.add(new CWriter(o)); + PM.add(new CWriter(o, getIntrinsicLowering())); return false; } diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index 25c940a6e1b..493e7ec5fcc 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -22,6 +22,7 @@ #include "llvm/PassManager.h" #include "llvm/SymbolTable.h" #include "llvm/Intrinsics.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Transforms/Scalar.h" @@ -37,16 +38,16 @@ using namespace llvm; namespace { class CWriter : public Pass, public InstVisitor { std::ostream &Out; + IntrinsicLowering &IL; Mangler *Mang; const Module *TheModule; FindUsedTypes *FUT; std::map TypeNames; - std::set MangledGlobals; std::map FPConstantMap; public: - CWriter(std::ostream &o) : Out(o) {} + CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {} void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -56,6 +57,9 @@ namespace { bool doInitialization(Module &M); bool run(Module &M) { + // First pass, lower all unhandled intrinsics. + lowerIntrinsics(M); + doInitialization(M); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) @@ -65,7 +69,6 @@ namespace { // Free memory... delete Mang; TypeNames.clear(); - MangledGlobals.clear(); return true; } @@ -77,6 +80,8 @@ namespace { void writeOperandInternal(Value *Operand); private : + void lowerIntrinsics(Module &M); + bool nameAllUsedStructureTypes(Module &M); void printModule(Module *M); void printFloatingPointConstants(Module &M); @@ -160,6 +165,7 @@ namespace { void printIndexingExpression(Value *Ptr, gep_type_iterator I, gep_type_iterator E); }; +} // Pass the Type* and the variable name and this prints out the variable // declaration. @@ -612,25 +618,6 @@ bool CWriter::doInitialization(Module &M) { bool Changed = nameAllUsedStructureTypes(M); Mang = new Mangler(M); - // Calculate which global values have names that will collide when we throw - // away type information. - { // Scope to delete the FoundNames set when we are done with it... - std::set FoundNames; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->hasName()) // If the global has a name... - if (FoundNames.count(I->getName())) // And the name is already used - MangledGlobals.insert(I); // Mangle the name - else - FoundNames.insert(I->getName()); // Otherwise, keep track of name - - for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (I->hasName()) // If the global has a name... - if (FoundNames.count(I->getName())) // And the name is already used - MangledGlobals.insert(I); // Mangle the name - else - FoundNames.insert(I->getName()); // Otherwise, keep track of name - } - // get declaration for alloca Out << "/* Provide Declarations */\n"; Out << "#include \n"; // Varargs support @@ -670,11 +657,8 @@ bool CWriter::doInitialization(Module &M) { if (!M.empty()) { Out << "\n/* Function Declarations */\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - // If the function is external and the name collides don't print it. - // Sometimes the bytecode likes to have multiple "declarations" for - // external functions - if ((I->hasInternalLinkage() || !MangledGlobals.count(I)) && - !I->getIntrinsicID() && + // Don't print declarations for intrinsic functions. + if (!I->getIntrinsicID() && I->getName() != "setjmp" && I->getName() != "longjmp") { printFunctionSignature(I, true); if (I->hasWeakLinkage()) Out << " __ATTRIBUTE_WEAK__"; @@ -1162,12 +1146,39 @@ void CWriter::visitCastInst(CastInst &I) { writeOperand(I.getOperand(0)); } +void CWriter::lowerIntrinsics(Module &M) { + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + 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(I++)) + if (Function *F = CI->getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::not_intrinsic: + case Intrinsic::va_start: + case Intrinsic::va_copy: + case Intrinsic::va_end: + // We directly implement these intrinsics + break; + default: + // All other intrinsic calls we must lower. + Instruction *Before = CI->getPrev(); + IL.LowerIntrinsicCall(CI); + if (Before) { // Move iterator to instruction after call + I = Before; ++I; + } else { + I = BB->begin(); + } + } +} + + + void CWriter::visitCallInst(CallInst &I) { // Handle intrinsic function calls first... if (Function *F = I.getCalledFunction()) if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) { switch (ID) { - default: assert(0 && "Unknown LLVM intrinsic!"); + default: assert(0 && "Unknown LLVM intrinsic!"); case Intrinsic::va_start: Out << "0; "; @@ -1194,38 +1205,6 @@ void CWriter::visitCallInst(CallInst &I) { writeOperand(I.getOperand(1)); Out << ")"; return; - case Intrinsic::setjmp: - case Intrinsic::sigsetjmp: - // This intrinsic should never exist in the program, but until we get - // setjmp/longjmp transformations going on, we should codegen it to - // something reasonable. This will allow code that never calls longjmp - // to work. - Out << "0"; - return; - case Intrinsic::longjmp: - case Intrinsic::siglongjmp: - // Longjmp is not implemented, and never will be. It would cause an - // exception throw. - Out << "abort()"; - return; - case Intrinsic::memcpy: - Out << "memcpy("; - writeOperand(I.getOperand(1)); - Out << ", "; - writeOperand(I.getOperand(2)); - Out << ", "; - writeOperand(I.getOperand(3)); - Out << ")"; - return; - case Intrinsic::memmove: - Out << "memmove("; - writeOperand(I.getOperand(1)); - Out << ", "; - writeOperand(I.getOperand(2)); - Out << ", "; - writeOperand(I.getOperand(3)); - Out << ")"; - return; } } visitCallSite(&I); @@ -1364,8 +1343,6 @@ void CWriter::visitVAArgInst(VAArgInst &I) { Out << ");\n va_end(Tmp); }"; } -} - //===----------------------------------------------------------------------===// // External Interface declaration //===----------------------------------------------------------------------===// @@ -1373,7 +1350,7 @@ void CWriter::visitVAArgInst(VAArgInst &I) { bool CTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &o) { PM.add(createLowerAllocationsPass()); PM.add(createLowerInvokePass()); - PM.add(new CWriter(o)); + PM.add(new CWriter(o, getIntrinsicLowering())); return false; }