# HG changeset patch # User Kaito Tokumori # Date 1373707009 -32400 # Node ID e3d004bb4de5fdd04156355d85800d8f0f668b6d # Parent 1d7e5c85e4cf90b0570ab2e13de2902f4aa8b1ee can tell the Type which is void or __code and set tail call flag only __code. diff -r 1d7e5c85e4cf -r e3d004bb4de5 include/llvm/IR/Type.h --- a/include/llvm/IR/Type.h Thu Jul 04 02:18:09 2013 +0900 +++ b/include/llvm/IR/Type.h Sat Jul 13 18:16:49 2013 +0900 @@ -71,6 +71,7 @@ ArrayTyID, ///< 13: Arrays PointerTyID, ///< 14: Pointers VectorTyID, ///< 15: SIMD 'packed' format, or other vector type + NumTypeIDs, // Must remain as last defined ID LastPrimitiveTyID = X86_MMXTyID, @@ -87,11 +88,18 @@ // Note: TypeID : low 8 bit; SubclassData : high 24 bit. uint32_t IDAndSubclassData; +#ifndef noCbC + bool is__Code; +#endif + protected: friend class LLVMContextImpl; explicit Type(LLVMContext &C, TypeID tid) : Context(C), IDAndSubclassData(0), NumContainedTys(0), ContainedTys(0) { +#ifndef noCbC + is__Code = false; +#endif setTypeID(tid); } ~Type() {} @@ -139,6 +147,13 @@ /// isVoidTy - Return true if this is 'void'. bool isVoidTy() const { return getTypeID() == VoidTyID; } +#ifndef noCbC + void set__CodeFlag(bool f) { is__Code = f;} + + /// is__CodeTy - Return true if this is '__code'. + bool is__CodeTy() const { return is__Code; } +#endif + /// isHalfTy - Return true if this is 'half', a 16-bit IEEE fp type. bool isHalfTy() const { return getTypeID() == HalfTyID; } diff -r 1d7e5c85e4cf -r e3d004bb4de5 include/llvm/LinkAllPasses.h --- a/include/llvm/LinkAllPasses.h Thu Jul 04 02:18:09 2013 +0900 +++ b/include/llvm/LinkAllPasses.h Sat Jul 13 18:16:49 2013 +0900 @@ -135,7 +135,11 @@ (void) llvm::createStripNonDebugSymbolsPass(); (void) llvm::createStripDeadDebugInfoPass(); (void) llvm::createStripDeadPrototypesPass(); +#ifndef noCbC + (void) llvm::createTailCallEliminationPass(false); +#else (void) llvm::createTailCallEliminationPass(); +#endif (void) llvm::createJumpThreadingPass(); (void) llvm::createUnifyFunctionExitNodesPass(); (void) llvm::createInstCountPass(); diff -r 1d7e5c85e4cf -r e3d004bb4de5 include/llvm/Transforms/Scalar.h --- a/include/llvm/Transforms/Scalar.h Thu Jul 04 02:18:09 2013 +0900 +++ b/include/llvm/Transforms/Scalar.h Sat Jul 13 18:16:49 2013 +0900 @@ -227,7 +227,11 @@ // TailCallElimination - This pass eliminates call instructions to the current // function which occur immediately before return instructions. // +#ifndef noCbC +FunctionPass *createTailCallEliminationPass(bool isOnlyForCbC); +#else FunctionPass *createTailCallEliminationPass(); +#endif //===----------------------------------------------------------------------===// // diff -r 1d7e5c85e4cf -r e3d004bb4de5 lib/IR/LLVMContextImpl.h --- a/lib/IR/LLVMContextImpl.h Thu Jul 04 02:18:09 2013 +0900 +++ b/lib/IR/LLVMContextImpl.h Sat Jul 13 18:16:49 2013 +0900 @@ -295,7 +295,6 @@ Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty; - /// TypeAllocator - All dynamically allocated types are allocated from this. /// They live forever until the context is torn down. diff -r 1d7e5c85e4cf -r e3d004bb4de5 lib/Transforms/IPO/PassManagerBuilder.cpp --- a/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Jul 04 02:18:09 2013 +0900 +++ b/lib/Transforms/IPO/PassManagerBuilder.cpp Sat Jul 13 18:16:49 2013 +0900 @@ -134,6 +134,9 @@ if (!GlobalExtensions->empty() || !Extensions.empty()) MPM.add(createBarrierNoopPass()); +#ifndef noCbC + MPM.add(createTailCallEliminationPass(true)); // Eliminate tail calls +#endif addExtensionsToPM(EP_EnabledOnOptLevel0, MPM); return; } @@ -181,7 +184,11 @@ MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createInstructionCombiningPass()); // Combine silly seq's +#ifndef noCbC + MPM.add(createTailCallEliminationPass(false)); // Eliminate tail calls +#else MPM.add(createTailCallEliminationPass()); // Eliminate tail calls +#endif MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createReassociatePass()); // Reassociate expressions MPM.add(createLoopRotatePass()); // Rotate Loop diff -r 1d7e5c85e4cf -r e3d004bb4de5 lib/Transforms/Scalar/Scalar.cpp --- a/lib/Transforms/Scalar/Scalar.cpp Thu Jul 04 02:18:09 2013 +0900 +++ b/lib/Transforms/Scalar/Scalar.cpp Sat Jul 13 18:16:49 2013 +0900 @@ -153,7 +153,11 @@ } void LLVMAddTailCallEliminationPass(LLVMPassManagerRef PM) { +#ifndef noCbC + unwrap(PM)->add(createTailCallEliminationPass(false)); +#else unwrap(PM)->add(createTailCallEliminationPass()); +#endif } void LLVMAddConstantPropagationPass(LLVMPassManagerRef PM) { diff -r 1d7e5c85e4cf -r e3d004bb4de5 lib/Transforms/Scalar/TailRecursionElimination.cpp --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp Thu Jul 04 02:18:09 2013 +0900 +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp Sat Jul 13 18:16:49 2013 +0900 @@ -86,7 +86,12 @@ TailCallElim() : FunctionPass(ID) { initializeTailCallElimPass(*PassRegistry::getPassRegistry()); } - +#ifndef noCbC + TailCallElim(bool f) : FunctionPass(ID) { + initializeTailCallElimPass(*PassRegistry::getPassRegistry()); + onlyForCbC = f; + } +#endif virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual bool runOnFunction(Function &F); @@ -110,6 +115,15 @@ bool CannotTailCallElimCallsMarkedTail); bool CanMoveAboveCall(Instruction *I, CallInst *CI); Value *CanTransformAccumulatorRecursion(Instruction *I, CallInst *CI); +#ifndef noCbC + bool onlyForCbC; +#endif + +#ifndef noCbC + public: + void setCbCFlag(bool f); + bool isOnlyForCbC(); +#endif }; } @@ -120,10 +134,17 @@ INITIALIZE_PASS_END(TailCallElim, "tailcallelim", "Tail Call Elimination", false, false) +#ifndef noCbC +// Public interface to the TailCallElimination pass +FunctionPass *llvm::createTailCallEliminationPass(bool isOnlyForCbC) { + return new TailCallElim(isOnlyForCbC); +} +#else // Public interface to the TailCallElimination pass FunctionPass *llvm::createTailCallEliminationPass() { return new TailCallElim(); } +#endif void TailCallElim::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -176,6 +197,18 @@ // doesn't). bool CannotTCETailMarkedCall = false; +#ifndef noCbC + if (!FunctionContainsEscapingAllocas && !F.callsFunctionThatReturnsTwice()) + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + if (CallInst *CI = dyn_cast(I)) { + if (CI->getCalledFunction()->getReturnType()->is__CodeTy()) { + CI->setTailCall(); + MadeChange = true; + } + } +#endif + // Loop over the function, looking for any returning blocks, and keeping track