/// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into /// an invoke, we have to turn all of the calls that can throw into /// invokes. This function analyze BB to see if there are any calls, and if so, /// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI /// nodes in that block with the values specified in InvokeDestPHIValues. /// /// Returns true to indicate that the next block should be skipped. static bool HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB, InvokeInliningInfo &Invoke) { LandingPadInst *LPI = Invoke.getLandingPadInst(); for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) { Instruction *I = BBI++; if (LandingPadInst *L = dyn_cast<LandingPadInst>(I)) { unsigned NumClauses = LPI->getNumClauses(); L->reserveClauses(NumClauses); for (unsigned i = 0; i != NumClauses; ++i) L->addClause(LPI->getClause(i)); } // We only need to check for function calls: inlined invoke // instructions require no special handling. CallInst *CI = dyn_cast<CallInst>(I); // If this call cannot unwind, don't convert it to an invoke. if (!CI || CI->doesNotThrow()) continue; // Convert this function call into an invoke instruction. First, split the // basic block. BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc"); // Delete the unconditional branch inserted by splitBasicBlock BB->getInstList().pop_back(); // Create the new invoke instruction. ImmutableCallSite CS(CI); SmallVector<Value*, 8> InvokeArgs(CS.arg_begin(), CS.arg_end()); InvokeInst *II = InvokeInst::Create(CI->getCalledValue(), Split, Invoke.getOuterResumeDest(), InvokeArgs, CI->getName(), BB); II->setCallingConv(CI->getCallingConv()); II->setAttributes(CI->getAttributes()); // Make sure that anything using the call now uses the invoke! This also // updates the CallGraph if present, because it uses a WeakVH. CI->replaceAllUsesWith(II); // Delete the original call Split->getInstList().pop_front(); // Update any PHI nodes in the exceptional block to indicate that there is // now a new entry in them. Invoke.addIncomingPHIValuesFor(BB); return false; } return false; }
/// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into /// an invoke, we have to turn all of the calls that can throw into /// invokes. This function analyze BB to see if there are any calls, and if so, /// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI /// nodes in that block with the values specified in InvokeDestPHIValues. /// static void HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB, BasicBlock *InvokeDest, const SmallVectorImpl<Value*> &InvokeDestPHIValues) { for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) { Instruction *I = BBI++; // We only need to check for function calls: inlined invoke // instructions require no special handling. CallInst *CI = dyn_cast<CallInst>(I); if (CI == 0) continue; // If this call cannot unwind, don't convert it to an invoke. if (CI->doesNotThrow()) continue; // Convert this function call into an invoke instruction. // First, split the basic block. BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc"); // Next, create the new invoke instruction, inserting it at the end // of the old basic block. ImmutableCallSite CS(CI); SmallVector<Value*, 8> InvokeArgs(CS.arg_begin(), CS.arg_end()); InvokeInst *II = InvokeInst::Create(CI->getCalledValue(), Split, InvokeDest, InvokeArgs.begin(), InvokeArgs.end(), CI->getName(), BB->getTerminator()); II->setCallingConv(CI->getCallingConv()); II->setAttributes(CI->getAttributes()); // Make sure that anything using the call now uses the invoke! This also // updates the CallGraph if present, because it uses a WeakVH. CI->replaceAllUsesWith(II); // Delete the unconditional branch inserted by splitBasicBlock BB->getInstList().pop_back(); Split->getInstList().pop_front(); // Delete the original call // Update any PHI nodes in the exceptional block to indicate that // there is now a new entry in them. unsigned i = 0; for (BasicBlock::iterator I = InvokeDest->begin(); isa<PHINode>(I); ++I, ++i) cast<PHINode>(I)->addIncoming(InvokeDestPHIValues[i], BB); // This basic block is now complete, the caller will continue scanning the // next one. return; } }
// visitCallInst - This converts all LLVM call instructions into invoke // instructions. The except part of the invoke goes to the "LongJmpBlkPre" // that grabs the exception and proceeds to determine if it's a longjmp // exception or not. void LowerSetJmp::visitCallInst(CallInst& CI) { if (CI.getCalledFunction()) if (!IsTransformableFunction(CI.getCalledFunction()->getName()) || CI.getCalledFunction()->isIntrinsic()) return; BasicBlock* OldBB = CI.getParent(); // If not reachable from a setjmp call, don't transform. if (!DFSBlocks.count(OldBB)) return; BasicBlock* NewBB = OldBB->splitBasicBlock(CI); assert(NewBB && "Couldn't split BB of \"call\" instruction!!"); DFSBlocks.insert(NewBB); NewBB->setName("Call2Invoke"); Function* Func = OldBB->getParent(); // Construct the new "invoke" instruction. TerminatorInst* Term = OldBB->getTerminator(); CallSite CS(&CI); std::vector<Value*> Params(CS.arg_begin(), CS.arg_end()); InvokeInst* II = InvokeInst::Create(CI.getCalledValue(), NewBB, PrelimBBMap[Func], Params.begin(), Params.end(), CI.getName(), Term); II->setCallingConv(CI.getCallingConv()); II->setAttributes(CI.getAttributes()); // Replace the old call inst with the invoke inst and remove the call. CI.replaceAllUsesWith(II); CI.eraseFromParent(); // The old terminator is useless now that we have the invoke inst. Term->eraseFromParent(); ++CallsTransformed; }
/// Replaces the given call site (Call or Invoke) with a gc.statepoint /// intrinsic with an empty deoptimization arguments list. This does /// NOT do explicit relocation for GC support. static Value *ReplaceWithStatepoint(const CallSite &CS /* to replace */) { assert(CS.getInstruction()->getModule() && "must be set"); // TODO: technically, a pass is not allowed to get functions from within a // function pass since it might trigger a new function addition. Refactor // this logic out to the initialization of the pass. Doesn't appear to // matter in practice. // Then go ahead and use the builder do actually do the inserts. We insert // immediately before the previous instruction under the assumption that all // arguments will be available here. We can't insert afterwards since we may // be replacing a terminator. IRBuilder<> Builder(CS.getInstruction()); // Note: The gc args are not filled in at this time, that's handled by // RewriteStatepointsForGC (which is currently under review). // Create the statepoint given all the arguments Instruction *Token = nullptr; uint64_t ID; uint32_t NumPatchBytes; AttributeSet OriginalAttrs = CS.getAttributes(); Attribute AttrID = OriginalAttrs.getAttribute(AttributeSet::FunctionIndex, "statepoint-id"); Attribute AttrNumPatchBytes = OriginalAttrs.getAttribute( AttributeSet::FunctionIndex, "statepoint-num-patch-bytes"); AttrBuilder AttrsToRemove; bool HasID = AttrID.isStringAttribute() && !AttrID.getValueAsString().getAsInteger(10, ID); if (HasID) AttrsToRemove.addAttribute("statepoint-id"); else ID = 0xABCDEF00; bool HasNumPatchBytes = AttrNumPatchBytes.isStringAttribute() && !AttrNumPatchBytes.getValueAsString().getAsInteger(10, NumPatchBytes); if (HasNumPatchBytes) AttrsToRemove.addAttribute("statepoint-num-patch-bytes"); else NumPatchBytes = 0; OriginalAttrs = OriginalAttrs.removeAttributes( CS.getInstruction()->getContext(), AttributeSet::FunctionIndex, AttrsToRemove); if (CS.isCall()) { CallInst *ToReplace = cast<CallInst>(CS.getInstruction()); CallInst *Call = Builder.CreateGCStatepointCall( ID, NumPatchBytes, CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None, "safepoint_token"); Call->setTailCall(ToReplace->isTailCall()); Call->setCallingConv(ToReplace->getCallingConv()); // In case if we can handle this set of attributes - set up function // attributes directly on statepoint and return attributes later for // gc_result intrinsic. Call->setAttributes(OriginalAttrs.getFnAttributes()); Token = Call; // Put the following gc_result and gc_relocate calls immediately after // the old call (which we're about to delete). assert(ToReplace->getNextNode() && "not a terminator, must have next"); Builder.SetInsertPoint(ToReplace->getNextNode()); Builder.SetCurrentDebugLocation(ToReplace->getNextNode()->getDebugLoc()); } else if (CS.isInvoke()) { InvokeInst *ToReplace = cast<InvokeInst>(CS.getInstruction()); // Insert the new invoke into the old block. We'll remove the old one in a // moment at which point this will become the new terminator for the // original block. Builder.SetInsertPoint(ToReplace->getParent()); InvokeInst *Invoke = Builder.CreateGCStatepointInvoke( ID, NumPatchBytes, CS.getCalledValue(), ToReplace->getNormalDest(), ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None, "safepoint_token"); Invoke->setCallingConv(ToReplace->getCallingConv()); // In case if we can handle this set of attributes - set up function // attributes directly on statepoint and return attributes later for // gc_result intrinsic. Invoke->setAttributes(OriginalAttrs.getFnAttributes()); Token = Invoke; // We'll insert the gc.result into the normal block BasicBlock *NormalDest = ToReplace->getNormalDest(); // Can not insert gc.result in case of phi nodes preset. // Should have removed this cases prior to running this function assert(!isa<PHINode>(NormalDest->begin())); Instruction *IP = &*(NormalDest->getFirstInsertionPt()); Builder.SetInsertPoint(IP); } else { llvm_unreachable("unexpect type of CallSite"); } assert(Token); // Handle the return value of the original call - update all uses to use a // gc_result hanging off the statepoint node we just inserted // Only add the gc_result iff there is actually a used result if (!CS.getType()->isVoidTy() && !CS.getInstruction()->use_empty()) { std::string TakenName = CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : ""; CallInst *GCResult = Builder.CreateGCResult(Token, CS.getType(), TakenName); GCResult->setAttributes(OriginalAttrs.getRetAttributes()); return GCResult; } else { // No return value for the call. return nullptr; } }
/// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls /// in the body of the inlined function into invokes and turn unwind /// instructions into branches to the invoke unwind dest. /// /// II is the invoke instruction being inlined. FirstNewBlock is the first /// block of the inlined code (the last block is the end of the function), /// and InlineCodeInfo is information about the code that got inlined. static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, ClonedCodeInfo &InlinedCodeInfo) { BasicBlock *InvokeDest = II->getUnwindDest(); std::vector<Value*> InvokeDestPHIValues; // If there are PHI nodes in the unwind destination block, we need to // keep track of which values came into them from this invoke, then remove // the entry for this block. BasicBlock *InvokeBlock = II->getParent(); for (BasicBlock::iterator I = InvokeDest->begin(); isa<PHINode>(I); ++I) { PHINode *PN = cast<PHINode>(I); // Save the value to use for this edge. InvokeDestPHIValues.push_back(PN->getIncomingValueForBlock(InvokeBlock)); } Function *Caller = FirstNewBlock->getParent(); // The inlined code is currently at the end of the function, scan from the // start of the inlined code to its end, checking for stuff we need to // rewrite. if (InlinedCodeInfo.ContainsCalls || InlinedCodeInfo.ContainsUnwinds) { for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB) { if (InlinedCodeInfo.ContainsCalls) { for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ){ Instruction *I = BBI++; // We only need to check for function calls: inlined invoke // instructions require no special handling. if (!isa<CallInst>(I)) continue; CallInst *CI = cast<CallInst>(I); // If this call cannot unwind, don't convert it to an invoke. if (CI->doesNotThrow()) continue; // Convert this function call into an invoke instruction. // First, split the basic block. BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc"); // Next, create the new invoke instruction, inserting it at the end // of the old basic block. SmallVector<Value*, 8> InvokeArgs(CI->op_begin()+1, CI->op_end()); InvokeInst *II = InvokeInst::Create(CI->getCalledValue(), Split, InvokeDest, InvokeArgs.begin(), InvokeArgs.end(), CI->getName(), BB->getTerminator()); II->setCallingConv(CI->getCallingConv()); II->setAttributes(CI->getAttributes()); // Make sure that anything using the call now uses the invoke! CI->replaceAllUsesWith(II); // Delete the unconditional branch inserted by splitBasicBlock BB->getInstList().pop_back(); Split->getInstList().pop_front(); // Delete the original call // Update any PHI nodes in the exceptional block to indicate that // there is now a new entry in them. unsigned i = 0; for (BasicBlock::iterator I = InvokeDest->begin(); isa<PHINode>(I); ++I, ++i) { PHINode *PN = cast<PHINode>(I); PN->addIncoming(InvokeDestPHIValues[i], BB); } // This basic block is now complete, start scanning the next one. break; } } if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) { // An UnwindInst requires special handling when it gets inlined into an // invoke site. Once this happens, we know that the unwind would cause // a control transfer to the invoke exception destination, so we can // transform it into a direct branch to the exception destination. BranchInst::Create(InvokeDest, UI); // Delete the unwind instruction! UI->eraseFromParent(); // Update any PHI nodes in the exceptional block to indicate that // there is now a new entry in them. unsigned i = 0; for (BasicBlock::iterator I = InvokeDest->begin(); isa<PHINode>(I); ++I, ++i) { PHINode *PN = cast<PHINode>(I); PN->addIncoming(InvokeDestPHIValues[i], BB); } } } } // Now that everything is happy, we have one final detail. The PHI nodes in // the exception destination block still have entries due to the original // invoke instruction. Eliminate these entries (which might even delete the // PHI node) now. InvokeDest->removePredecessor(II->getParent()); }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. // Clone functions that take GEPs as arguments // // Inputs: // M - A reference to the LLVM module to transform // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool GEPExprArgs::runOnModule(Module& M) { bool changed; do { changed = false; for (Module::iterator F = M.begin(); F != M.end(); ++F){ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { CallInst *CI = dyn_cast<CallInst>(I++); if(!CI) continue; if(CI->hasByValArgument()) continue; // if the GEP calls a function, that is externally defined, // or might be changed, ignore this call site. Function *F = CI->getCalledFunction(); if (!F || (F->isDeclaration() || F->mayBeOverridden())) continue; if(F->hasStructRetAttr()) continue; if(F->isVarArg()) continue; // find the argument we must replace Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end(); unsigned argNum = 1; for(; argNum < CI->getNumOperands();argNum++, ++ai) { if(ai->use_empty()) continue; if (isa<GEPOperator>(CI->getOperand(argNum))) break; } // if no argument was a GEP operator to be changed if(ai == ae) continue; GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum)); if(!GEP->hasAllConstantIndices()) continue; // Construct the new Type // Appends the struct Type at the beginning std::vector<Type*>TP; TP.push_back(GEP->getPointerOperand()->getType()); for(unsigned c = 1; c < CI->getNumOperands();c++) { TP.push_back(CI->getOperand(c)->getType()); } //return type is same as that of original instruction FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false); Function *NewF; numSimplified++; if(numSimplified > 800) return true; NewF = Function::Create(NewFTy, GlobalValue::InternalLinkage, F->getName().str() + ".TEST", &M); Function::arg_iterator NI = NewF->arg_begin(); NI->setName("GEParg"); ++NI; ValueToValueMapTy ValueMap; for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) { ValueMap[II] = NI; NI->setName(II->getName()); NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1)); } NewF->setAttributes(NewF->getAttributes().addAttr( 0, F->getAttributes().getRetAttributes())); // Perform the cloning. SmallVector<ReturnInst*,100> Returns; CloneFunctionInto(NewF, F, ValueMap, false, Returns); std::vector<Value*> fargs; for(Function::arg_iterator ai = NewF->arg_begin(), ae= NewF->arg_end(); ai != ae; ++ai) { fargs.push_back(ai); } NewF->setAttributes(NewF->getAttributes().addAttr( ~0, F->getAttributes().getFnAttributes())); //Get the point to insert the GEP instr. SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end()); Instruction *InsertPoint; for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;} NI = NewF->arg_begin(); SmallVector<Value*, 8> Indices; Indices.append(GEP->op_begin()+1, GEP->op_end()); GetElementPtrInst *GEP_new = GetElementPtrInst::Create(cast<Value>(NI), Indices, "", InsertPoint); fargs.at(argNum)->replaceAllUsesWith(GEP_new); unsigned j = argNum + 1; for(; j < CI->getNumOperands();j++) { if(CI->getOperand(j) == GEP) fargs.at(j)->replaceAllUsesWith(GEP_new); } SmallVector<AttributeWithIndex, 8> AttributesVec; // Get the initial attributes of the call AttrListPtr CallPAL = CI->getAttributes(); Attributes RAttrs = CallPAL.getRetAttributes(); Attributes FnAttrs = CallPAL.getFnAttributes(); if (RAttrs) AttributesVec.push_back(AttributeWithIndex::get(0, RAttrs)); SmallVector<Value*, 8> Args; Args.push_back(GEP->getPointerOperand()); for(unsigned j =1;j<CI->getNumOperands();j++) { Args.push_back(CI->getOperand(j)); // position in the AttributesVec if (Attributes Attrs = CallPAL.getParamAttributes(j)) AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs)); } // Create the new attributes vec. if (FnAttrs != Attribute::None) AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs)); AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec.begin(), AttributesVec.end()); CallInst *CallI = CallInst::Create(NewF,Args,"", CI); CallI->setCallingConv(CI->getCallingConv()); CallI->setAttributes(NewCallPAL); CI->replaceAllUsesWith(CallI); CI->eraseFromParent(); changed = true; } } } } while(changed); return true; }
/// Replaces the given call site (Call or Invoke) with a gc.statepoint /// intrinsic with an empty deoptimization arguments list. This does /// NOT do explicit relocation for GC support. static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ Pass *P) { BasicBlock *BB = CS.getInstruction()->getParent(); Function *F = BB->getParent(); Module *M = F->getParent(); assert(M && "must be set"); // TODO: technically, a pass is not allowed to get functions from within a // function pass since it might trigger a new function addition. Refactor // this logic out to the initialization of the pass. Doesn't appear to // matter in practice. // Fill in the one generic type'd argument (the function is also vararg) std::vector<Type *> argTypes; argTypes.push_back(CS.getCalledValue()->getType()); Function *gc_statepoint_decl = Intrinsic::getDeclaration( M, Intrinsic::experimental_gc_statepoint, argTypes); // Then go ahead and use the builder do actually do the inserts. We insert // immediately before the previous instruction under the assumption that all // arguments will be available here. We can't insert afterwards since we may // be replacing a terminator. Instruction *insertBefore = CS.getInstruction(); IRBuilder<> Builder(insertBefore); // First, create the statepoint (with all live ptrs as arguments). std::vector<llvm::Value *> args; // target, #args, unused, args Value *Target = CS.getCalledValue(); args.push_back(Target); int callArgSize = CS.arg_size(); args.push_back( ConstantInt::get(Type::getInt32Ty(M->getContext()), callArgSize)); // TODO: add a 'Needs GC-rewrite' later flag args.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 0)); // Copy all the arguments of the original call args.insert(args.end(), CS.arg_begin(), CS.arg_end()); // Create the statepoint given all the arguments Instruction *token = nullptr; AttributeSet return_attributes; if (CS.isCall()) { CallInst *toReplace = cast<CallInst>(CS.getInstruction()); CallInst *call = Builder.CreateCall(gc_statepoint_decl, args, "safepoint_token"); call->setTailCall(toReplace->isTailCall()); call->setCallingConv(toReplace->getCallingConv()); // Before we have to worry about GC semantics, all attributes are legal AttributeSet new_attrs = toReplace->getAttributes(); // In case if we can handle this set of sttributes - set up function attrs // directly on statepoint and return attrs later for gc_result intrinsic. call->setAttributes(new_attrs.getFnAttributes()); return_attributes = new_attrs.getRetAttributes(); // TODO: handle param attributes token = call; // Put the following gc_result and gc_relocate calls immediately after the // the old call (which we're about to delete) BasicBlock::iterator next(toReplace); assert(BB->end() != next && "not a terminator, must have next"); next++; Instruction *IP = &*(next); Builder.SetInsertPoint(IP); Builder.SetCurrentDebugLocation(IP->getDebugLoc()); } else if (CS.isInvoke()) { InvokeInst *toReplace = cast<InvokeInst>(CS.getInstruction()); // Insert the new invoke into the old block. We'll remove the old one in a // moment at which point this will become the new terminator for the // original block. InvokeInst *invoke = InvokeInst::Create( gc_statepoint_decl, toReplace->getNormalDest(), toReplace->getUnwindDest(), args, "", toReplace->getParent()); invoke->setCallingConv(toReplace->getCallingConv()); // Currently we will fail on parameter attributes and on certain // function attributes. AttributeSet new_attrs = toReplace->getAttributes(); // In case if we can handle this set of sttributes - set up function attrs // directly on statepoint and return attrs later for gc_result intrinsic. invoke->setAttributes(new_attrs.getFnAttributes()); return_attributes = new_attrs.getRetAttributes(); token = invoke; // We'll insert the gc.result into the normal block BasicBlock *normalDest = normalizeBBForInvokeSafepoint( toReplace->getNormalDest(), invoke->getParent()); Instruction *IP = &*(normalDest->getFirstInsertionPt()); Builder.SetInsertPoint(IP); } else { llvm_unreachable("unexpect type of CallSite"); } assert(token); // Handle the return value of the original call - update all uses to use a // gc_result hanging off the statepoint node we just inserted // Only add the gc_result iff there is actually a used result if (!CS.getType()->isVoidTy() && !CS.getInstruction()->use_empty()) { Instruction *gc_result = nullptr; std::vector<Type *> types; // one per 'any' type types.push_back(CS.getType()); // result type auto get_gc_result_id = [&](Type &Ty) { if (Ty.isIntegerTy()) { return Intrinsic::experimental_gc_result_int; } else if (Ty.isFloatingPointTy()) { return Intrinsic::experimental_gc_result_float; } else if (Ty.isPointerTy()) { return Intrinsic::experimental_gc_result_ptr; } else { llvm_unreachable("non java type encountered"); } }; Intrinsic::ID Id = get_gc_result_id(*CS.getType()); Value *gc_result_func = Intrinsic::getDeclaration(M, Id, types); std::vector<Value *> args; args.push_back(token); gc_result = Builder.CreateCall( gc_result_func, args, CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : ""); cast<CallInst>(gc_result)->setAttributes(return_attributes); return gc_result; } else { // No return value for the call. return nullptr; } }
/// Replaces the given call site (Call or Invoke) with a gc.statepoint /// intrinsic with an empty deoptimization arguments list. This does /// NOT do explicit relocation for GC support. static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ Pass *P) { assert(CS.getInstruction()->getParent()->getParent()->getParent() && "must be set"); // TODO: technically, a pass is not allowed to get functions from within a // function pass since it might trigger a new function addition. Refactor // this logic out to the initialization of the pass. Doesn't appear to // matter in practice. // Then go ahead and use the builder do actually do the inserts. We insert // immediately before the previous instruction under the assumption that all // arguments will be available here. We can't insert afterwards since we may // be replacing a terminator. IRBuilder<> Builder(CS.getInstruction()); // Note: The gc args are not filled in at this time, that's handled by // RewriteStatepointsForGC (which is currently under review). // Create the statepoint given all the arguments Instruction *Token = nullptr; AttributeSet OriginalAttrs; if (CS.isCall()) { CallInst *ToReplace = cast<CallInst>(CS.getInstruction()); CallInst *Call = Builder.CreateGCStatepointCall( CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None, "safepoint_token"); Call->setTailCall(ToReplace->isTailCall()); Call->setCallingConv(ToReplace->getCallingConv()); // Before we have to worry about GC semantics, all attributes are legal // TODO: handle param attributes OriginalAttrs = ToReplace->getAttributes(); // In case if we can handle this set of attributes - set up function // attributes directly on statepoint and return attributes later for // gc_result intrinsic. Call->setAttributes(OriginalAttrs.getFnAttributes()); Token = Call; // Put the following gc_result and gc_relocate calls immediately after the // the old call (which we're about to delete). assert(ToReplace->getNextNode() && "not a terminator, must have next"); Builder.SetInsertPoint(ToReplace->getNextNode()); Builder.SetCurrentDebugLocation(ToReplace->getNextNode()->getDebugLoc()); } else if (CS.isInvoke()) { InvokeInst *ToReplace = cast<InvokeInst>(CS.getInstruction()); // Insert the new invoke into the old block. We'll remove the old one in a // moment at which point this will become the new terminator for the // original block. Builder.SetInsertPoint(ToReplace->getParent()); InvokeInst *Invoke = Builder.CreateGCStatepointInvoke( CS.getCalledValue(), ToReplace->getNormalDest(), ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()), Builder.getInt32(0), None, "safepoint_token"); // Currently we will fail on parameter attributes and on certain // function attributes. OriginalAttrs = ToReplace->getAttributes(); // In case if we can handle this set of attributes - set up function // attributes directly on statepoint and return attributes later for // gc_result intrinsic. Invoke->setAttributes(OriginalAttrs.getFnAttributes()); Token = Invoke; // We'll insert the gc.result into the normal block BasicBlock *NormalDest = normalizeBBForInvokeSafepoint( ToReplace->getNormalDest(), Invoke->getParent()); Builder.SetInsertPoint(NormalDest->getFirstInsertionPt()); } else { llvm_unreachable("unexpect type of CallSite"); } assert(Token); // Handle the return value of the original call - update all uses to use a // gc_result hanging off the statepoint node we just inserted // Only add the gc_result iff there is actually a used result if (!CS.getType()->isVoidTy() && !CS.getInstruction()->use_empty()) { std::string TakenName = CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : ""; CallInst *GCResult = Builder.CreateGCResult(Token, CS.getType(), TakenName); GCResult->setAttributes(OriginalAttrs.getRetAttributes()); return GCResult; } else { // No return value for the call. return nullptr; } }
int compile(list<string> args, list<string> kgen_args, string merge, list<string> merge_args, string input, string output, int arch, string host_compiler, string fileprefix) { // // The LLVM compiler to emit IR. // const char* llvm_compiler = "kernelgen-gfortran"; // // Interpret kernelgen compile options. // for (list<string>::iterator iarg = kgen_args.begin(), iearg = kgen_args.end(); iarg != iearg; iarg++) { const char* arg = (*iarg).c_str(); if (!strncmp(arg, "-Wk,--llvm-compiler=", 20)) llvm_compiler = arg + 20; } // // Generate temporary output file. // Check if output file is specified in the command line. // Replace or add output to the temporary file. // cfiledesc tmp_output = cfiledesc::mktemp(fileprefix); bool output_specified = false; for (list<string>::iterator iarg = args.begin(), iearg = args.end(); iarg != iearg; iarg++) { const char* arg = (*iarg).c_str(); if (!strcmp(arg, "-o")) { iarg++; *iarg = tmp_output.getFilename(); output_specified = true; break; } } if (!output_specified) { args.push_back("-o"); args.push_back(tmp_output.getFilename()); } // // 1) Compile source code using regular host compiler. // { if (verbose) { cout << host_compiler; for (list<string>::iterator iarg = args.begin(), iearg = args.end(); iarg != iearg; iarg++) cout << " " << *iarg; cout << endl; } int status = execute(host_compiler, args, "", NULL, NULL); if (status) return status; } // // 2) Emit LLVM IR. // string out = ""; { list<string> emit_ir_args; for (list<string>::iterator iarg = args.begin(), iearg = args.end(); iarg != iearg; iarg++) { const char* arg = (*iarg).c_str(); if (!strcmp(arg, "-c") || !strcmp(arg, "-o")) { iarg++; continue; } if (!strcmp(arg, "-g")) { continue; } emit_ir_args.push_back(*iarg); } emit_ir_args.push_back("-fplugin=/opt/kernelgen/lib/dragonegg.so"); emit_ir_args.push_back("-fplugin-arg-dragonegg-emit-ir"); emit_ir_args.push_back("-S"); emit_ir_args.push_back(input); emit_ir_args.push_back("-o"); emit_ir_args.push_back("-"); if (verbose) { cout << llvm_compiler; for (list<string>::iterator iarg = emit_ir_args.begin(), iearg = emit_ir_args.end(); iarg != iearg; iarg++) cout << " " << *iarg; cout << endl; } int status = execute(llvm_compiler, emit_ir_args, "", &out, NULL); if (status) return status; } // // 3) Record existing module functions. // LLVMContext &context = getGlobalContext(); SMDiagnostic diag; MemoryBuffer* buffer1 = MemoryBuffer::getMemBuffer(out); auto_ptr<Module> m1; m1.reset(ParseIR(buffer1, diag, context)); //m1.get()->dump(); // // 4) Inline calls and extract loops into new functions. // MemoryBuffer* buffer2 = MemoryBuffer::getMemBuffer(out); auto_ptr<Module> m2; m2.reset(ParseIR(buffer2, diag, context)); { PassManager manager; manager.add(createInstructionCombiningPass()); manager.run(*m2.get()); } std::vector<CallInst *> LoopFuctionCalls; { PassManager manager; manager.add(createBranchedLoopExtractorPass(LoopFuctionCalls)); manager.run(*m2.get()); } //m2.get()->dump(); // // 5) Replace call to loop functions with call to launcher. // Append "always inline" attribute to all other functions. // Type* int32Ty = Type::getInt32Ty(context); Function* launch = Function::Create( TypeBuilder<types::i<32>(types::i<8>*, types::i<64>, types::i<32>*), true>::get(context), GlobalValue::ExternalLinkage, "kernelgen_launch", m2.get()); for (Module::iterator f1 = m2.get()->begin(), fe1 = m2.get()->end(); f1 != fe1; f1++) { Function* func = f1; if (func->isDeclaration()) continue; // Search for the current function in original module // functions list. // If function is not in list of original module, then // it is generated by the loop extractor. // Append "always inline" attribute to all other functions. if (m1.get()->getFunction(func->getName())) { const AttrListPtr attr = func->getAttributes(); const AttrListPtr attr_new = attr.addAttr(~0U, Attribute::AlwaysInline); func->setAttributes(attr_new); continue; } // Each such function must be extracted to the // standalone module and packed into resulting // object file data section. if (verbose) cout << "Preparing loop function " << func->getName().data() << " ..." << endl; // Reset to default visibility. func->setVisibility(GlobalValue::DefaultVisibility); // Reset to default linkage. func->setLinkage(GlobalValue::ExternalLinkage); // Replace call to this function in module with call to launcher. bool found = false; for (Module::iterator f2 = m2->begin(), fe2 = m2->end(); (f2 != fe2) && !found; f2++) for (Function::iterator bb = f2->begin(); (bb != f2->end()) && !found; bb++) for (BasicBlock::iterator i = bb->begin(); i != bb->end(); i++) { // Check if instruction in focus is a call. CallInst* call = dyn_cast<CallInst>(cast<Value>(i)); if (!call) continue; // Check if function is called (needs -instcombine pass). Function* callee = call->getCalledFunction(); if (!callee) continue; if (callee->isDeclaration()) continue; if (callee->getName() != func->getName()) continue; // Create a constant array holding original called // function name. Constant* name = ConstantArray::get( context, callee->getName(), true); // Create and initialize the memory buffer for name. ArrayType* nameTy = cast<ArrayType>(name->getType()); AllocaInst* nameAlloc = new AllocaInst(nameTy, "", call); StoreInst* nameInit = new StoreInst(name, nameAlloc, "", call); Value* Idx[2]; Idx[0] = Constant::getNullValue(Type::getInt32Ty(context)); Idx[1] = ConstantInt::get(Type::getInt32Ty(context), 0); GetElementPtrInst* namePtr = GetElementPtrInst::Create(nameAlloc, Idx, "", call); // Add pointer to the original function string name. SmallVector<Value*, 16> call_args; call_args.push_back(namePtr); // Add size of the aggregated arguments structure. { BitCastInst* BC = new BitCastInst( call->getArgOperand(0), Type::getInt64PtrTy(context), "", call); LoadInst* LI = new LoadInst(BC, "", call); call_args.push_back(LI); } // Add original aggregated structure argument. call_args.push_back(call->getArgOperand(0)); // Create new function call with new call arguments // and copy old call properties. CallInst* newcall = CallInst::Create(launch, call_args, "", call); //newcall->takeName(call); newcall->setCallingConv(call->getCallingConv()); newcall->setAttributes(call->getAttributes()); newcall->setDebugLoc(call->getDebugLoc()); // Replace old call with new one. call->replaceAllUsesWith(newcall); call->eraseFromParent(); found = true; break; } } //m2.get()->dump(); // // 6) Apply optimization passes to the resulting common // module. // { PassManager manager; manager.add(createLowerSetJmpPass()); PassManagerBuilder builder; builder.Inliner = createFunctionInliningPass(); builder.OptLevel = 3; builder.DisableSimplifyLibCalls = true; builder.populateModulePassManager(manager); manager.run(*m2.get()); } //m2.get()->dump(); // // 7) Embed the resulting module into object file. // { string ir_string; raw_string_ostream ir(ir_string); ir << (*m2.get()); celf e(tmp_output.getFilename(), output); e.getSection(".data")->addSymbol( "__kernelgen_" + string(input), ir_string.c_str(), ir_string.size() + 1); } return 0; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. // Clone functions that take LoadInsts as arguments // // Inputs: // M - A reference to the LLVM module to transform // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool LoadArgs::runOnModule(Module& M) { std::map<std::pair<Function*, const Type * > , Function* > fnCache; bool changed; do { changed = false; for (Module::iterator Func = M.begin(); Func != M.end(); ++Func) { for (Function::iterator B = Func->begin(), FE = Func->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { CallInst *CI = dyn_cast<CallInst>(I++); if(!CI) continue; if(CI->hasByValArgument()) continue; // if the CallInst calls a function, that is externally defined, // or might be changed, ignore this call site. Function *F = CI->getCalledFunction(); if (!F || (F->isDeclaration() || F->mayBeOverridden())) continue; if(F->hasStructRetAttr()) continue; if(F->isVarArg()) continue; // find the argument we must replace Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end(); unsigned argNum = 0; for(; argNum < CI->getNumArgOperands();argNum++, ++ai) { // do not care about dead arguments if(ai->use_empty()) continue; if(F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::SExt) || F->getAttributes().getParamAttributes(argNum).hasAttrSomewhere(Attribute::ZExt)) continue; if (isa<LoadInst>(CI->getArgOperand(argNum))) break; } // if no argument was a GEP operator to be changed if(ai == ae) continue; LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(argNum)); Instruction * InsertPt = &(Func->getEntryBlock().front()); AllocaInst *NewVal = new AllocaInst(LI->getType(), "",InsertPt); StoreInst *Copy = new StoreInst(LI, NewVal); Copy->insertAfter(LI); /*if(LI->getParent() != CI->getParent()) continue; // Also check that there is no store after the load. // TODO: Check if the load/store do not alias. BasicBlock::iterator bii = LI->getParent()->begin(); Instruction *BII = bii; while(BII != LI) { ++bii; BII = bii; } while(BII != CI) { if(isa<StoreInst>(BII)) break; ++bii; BII = bii; } if(isa<StoreInst>(bii)){ continue; }*/ // Construct the new Type // Appends the struct Type at the beginning std::vector<Type*>TP; for(unsigned c = 0; c < CI->getNumArgOperands();c++) { if(c == argNum) TP.push_back(LI->getPointerOperand()->getType()); TP.push_back(CI->getArgOperand(c)->getType()); } //return type is same as that of original instruction FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false); numSimplified++; //if(numSimplified > 1000) //return true; Function *NewF; std::map<std::pair<Function*, const Type* > , Function* >::iterator Test; Test = fnCache.find(std::make_pair(F, NewFTy)); if(Test != fnCache.end()) { NewF = Test->second; } else { NewF = Function::Create(NewFTy, GlobalValue::InternalLinkage, F->getName().str() + ".TEST", &M); fnCache[std::make_pair(F, NewFTy)] = NewF; Function::arg_iterator NI = NewF->arg_begin(); ValueToValueMapTy ValueMap; unsigned count = 0; for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++count, ++NI) { if(count == argNum) { NI->setName("LDarg"); continue; } ValueMap[II] = NI; NI->setName(II->getName()); NI->addAttr(F->getAttributes().getParamAttributes(II->getArgNo() + 1)); ++II; } // Perform the cloning. SmallVector<ReturnInst*,100> Returns; CloneFunctionInto(NewF, F, ValueMap, false, Returns); std::vector<Value*> fargs; for(Function::arg_iterator ai = NewF->arg_begin(), ae= NewF->arg_end(); ai != ae; ++ai) { fargs.push_back(ai); } NewF->setAttributes(NewF->getAttributes().addAttributes( F->getContext(), 0, F->getAttributes().getRetAttributes())); NewF->setAttributes(NewF->getAttributes().addAttributes( F->getContext(), ~0, F->getAttributes().getFnAttributes())); //Get the point to insert the GEP instr. Instruction *InsertPoint; for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;} LoadInst *LI_new = new LoadInst(fargs.at(argNum), "", InsertPoint); fargs.at(argNum+1)->replaceAllUsesWith(LI_new); } //this does not seem to be a good idea AttributeSet NewCallPAL=AttributeSet(); // Get the initial attributes of the call AttributeSet CallPAL = CI->getAttributes(); AttributeSet RAttrs = CallPAL.getRetAttributes(); AttributeSet FnAttrs = CallPAL.getFnAttributes(); if (!RAttrs.isEmpty()) NewCallPAL=NewCallPAL.addAttributes(F->getContext(),0, RAttrs); SmallVector<Value*, 8> Args; for(unsigned j =0;j<CI->getNumArgOperands();j++) { if(j == argNum) { Args.push_back(NewVal); } Args.push_back(CI->getArgOperand(j)); // position in the NewCallPAL AttributeSet Attrs = CallPAL.getParamAttributes(j+1); if (!Attrs.isEmpty()) NewCallPAL=NewCallPAL.addAttributes(F->getContext(),Args.size(), Attrs); } // Create the new attributes vec. if (!FnAttrs.isEmpty()) NewCallPAL=NewCallPAL.addAttributes(F->getContext(),~0, FnAttrs); CallInst *CallI = CallInst::Create(NewF,Args,"", CI); CallI->setCallingConv(CI->getCallingConv()); CallI->setAttributes(NewCallPAL); CI->replaceAllUsesWith(CallI); CI->eraseFromParent(); changed = true; } } } } while(changed); return true; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. // Search for all call sites to casted functions. // Check if they only differ in an argument type // Cast the argument, and call the original function // // Inputs: // M - A reference to the LLVM module to transform // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool ArgCast::runOnModule(Module& M) { std::vector<CallInst*> worklist; for (Module::iterator I = M.begin(); I != M.end(); ++I) { if (I->mayBeOverridden()) continue; // Find all uses of this function for(Value::user_iterator ui = I->user_begin(), ue = I->user_end(); ui != ue; ) { // check if is ever casted to a different function type ConstantExpr *CE = dyn_cast<ConstantExpr>(*ui++); if(!CE) continue; if (CE->getOpcode() != Instruction::BitCast) continue; if(CE->getOperand(0) != I) continue; const PointerType *PTy = dyn_cast<PointerType>(CE->getType()); if (!PTy) continue; const Type *ETy = PTy->getElementType(); const FunctionType *FTy = dyn_cast<FunctionType>(ETy); if(!FTy) continue; // casting to a varargs funtion // or function with same number of arguments // possibly varying types of arguments if(FTy->getNumParams() != I->arg_size() && !FTy->isVarArg()) continue; for(Value::user_iterator uii = CE->user_begin(), uee = CE->user_end(); uii != uee; ++uii) { // Find all uses of the casted value, and check if it is // used in a Call Instruction if (CallInst* CI = dyn_cast<CallInst>(*uii)) { // Check that it is the called value, and not an argument if(CI->getCalledValue() != CE) continue; // Check that the number of arguments passed, and expected // by the function are the same. if(!I->isVarArg()) { if(CI->getNumOperands() != I->arg_size() + 1) continue; } else { if(CI->getNumOperands() < I->arg_size() + 1) continue; } // If so, add to worklist worklist.push_back(CI); } } } } // Proces the worklist of potential call sites to transform while(!worklist.empty()) { CallInst *CI = worklist.back(); worklist.pop_back(); // Get the called Function Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts()); const FunctionType *FTy = F->getFunctionType(); SmallVector<Value*, 8> Args; unsigned i =0; for(i =0; i< FTy->getNumParams(); ++i) { Type *ArgType = CI->getOperand(i+1)->getType(); Type *FormalType = FTy->getParamType(i); // If the types for this argument match, just add it to the // parameter list. No cast needs to be inserted. if(ArgType == FormalType) { Args.push_back(CI->getOperand(i+1)); } else if(ArgType->isPointerTy() && FormalType->isPointerTy()) { CastInst *CastI = CastInst::CreatePointerCast(CI->getOperand(i+1), FormalType, "", CI); Args.push_back(CastI); } else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) { unsigned SrcBits = ArgType->getScalarSizeInBits(); unsigned DstBits = FormalType->getScalarSizeInBits(); if(SrcBits > DstBits) { CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), FormalType, true, "", CI); Args.push_back(CastI); } else { if (F->getAttributes().hasAttribute(i+1, Attribute::SExt)) { CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), FormalType, true, "", CI); Args.push_back(CastI); } else if (F->getAttributes().hasAttribute(i+1, Attribute::ZExt)) { CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), FormalType, false, "", CI); Args.push_back(CastI); } else { // Use ZExt in default case. // Derived from InstCombine. Also, the only reason this should happen // is mismatched prototypes. // Seen in case of integer constants which get interpreted as i32, // even if being used as i64. // TODO: is this correct? CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), FormalType, false, "", CI); Args.push_back(CastI); } } } else { DEBUG(ArgType->dump()); DEBUG(FormalType->dump()); break; } } // If we found an argument we could not cast, try the next instruction if(i != FTy->getNumParams()) { continue; } if(FTy->isVarArg()) { for(; i< CI->getNumOperands() - 1 ;i++) { Args.push_back(CI->getOperand(i+1)); } } // else replace the call instruction CallInst *CINew = CallInst::Create(F, Args, "", CI); CINew->setCallingConv(CI->getCallingConv()); CINew->setAttributes(CI->getAttributes()); if(!CI->use_empty()) { CastInst *RetCast; if(CI->getType() != CINew->getType()) { if(CI->getType()->isPointerTy() && CINew->getType()->isPointerTy()) RetCast = CastInst::CreatePointerCast(CINew, CI->getType(), "", CI); else if(CI->getType()->isIntOrIntVectorTy() && CINew->getType()->isIntOrIntVectorTy()) RetCast = CastInst::CreateIntegerCast(CINew, CI->getType(), false, "", CI); else if(CI->getType()->isIntOrIntVectorTy() && CINew->getType()->isPointerTy()) RetCast = CastInst::CreatePointerCast(CINew, CI->getType(), "", CI); else if(CI->getType()->isPointerTy() && CINew->getType()->isIntOrIntVectorTy()) RetCast = new IntToPtrInst(CINew, CI->getType(), "", CI); else { // TODO: I'm not sure what right behavior is here, but this case should be handled. llvm_unreachable("Unexpected type conversion in call!"); abort(); } CI->replaceAllUsesWith(RetCast); } else { CI->replaceAllUsesWith(CINew); } } // Debug printing DEBUG(errs() << "ARGCAST:"); DEBUG(errs() << "ERASE:"); DEBUG(CI->dump()); DEBUG(errs() << "ARGCAST:"); DEBUG(errs() << "ADDED:"); DEBUG(CINew->dump()); CI->eraseFromParent(); numChanged++; } return true; }
/// HandleCallsInBlockInlinedThroughInvoke - When we inline a basic block into /// an invoke, we have to turn all of the calls that can throw into /// invokes. This function analyze BB to see if there are any calls, and if so, /// it rewrites them to be invokes that jump to InvokeDest and fills in the PHI /// nodes in that block with the values specified in InvokeDestPHIValues. /// /// Returns true to indicate that the next block should be skipped. static bool HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB, InvokeInliningInfo &Invoke) { for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) { Instruction *I = BBI++; // We only need to check for function calls: inlined invoke // instructions require no special handling. CallInst *CI = dyn_cast<CallInst>(I); if (CI == 0) continue; // LIBUNWIND: merge selector instructions. if (EHSelectorInst *Inner = dyn_cast<EHSelectorInst>(CI)) { EHSelectorInst *Outer = Invoke.getOuterSelector(); if (!Outer) continue; bool innerIsOnlyCleanup = isCleanupOnlySelector(Inner); bool outerIsOnlyCleanup = isCleanupOnlySelector(Outer); // If both selectors contain only cleanups, we don't need to do // anything. TODO: this is really just a very specific instance // of a much more general optimization. if (innerIsOnlyCleanup && outerIsOnlyCleanup) continue; // Otherwise, we just append the outer selector to the inner selector. SmallVector<Value*, 16> NewSelector; for (unsigned i = 0, e = Inner->getNumArgOperands(); i != e; ++i) NewSelector.push_back(Inner->getArgOperand(i)); for (unsigned i = 2, e = Outer->getNumArgOperands(); i != e; ++i) NewSelector.push_back(Outer->getArgOperand(i)); CallInst *NewInner = IRBuilder<>(Inner).CreateCall(Inner->getCalledValue(), NewSelector); // No need to copy attributes, calling convention, etc. NewInner->takeName(Inner); Inner->replaceAllUsesWith(NewInner); Inner->eraseFromParent(); continue; } // If this call cannot unwind, don't convert it to an invoke. if (CI->doesNotThrow()) continue; // Convert this function call into an invoke instruction. // First, split the basic block. BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc"); // Delete the unconditional branch inserted by splitBasicBlock BB->getInstList().pop_back(); // LIBUNWIND: If this is a call to @llvm.eh.resume, just branch // directly to the new landing pad. if (Invoke.forwardEHResume(CI, BB)) { // TODO: 'Split' is now unreachable; clean it up. // We want to leave the original call intact so that the call // graph and other structures won't get misled. We also have to // avoid processing the next block, or we'll iterate here forever. return true; } // Otherwise, create the new invoke instruction. ImmutableCallSite CS(CI); SmallVector<Value*, 8> InvokeArgs(CS.arg_begin(), CS.arg_end()); InvokeInst *II = InvokeInst::Create(CI->getCalledValue(), Split, Invoke.getOuterUnwindDest(), InvokeArgs, CI->getName(), BB); II->setCallingConv(CI->getCallingConv()); II->setAttributes(CI->getAttributes()); // Make sure that anything using the call now uses the invoke! This also // updates the CallGraph if present, because it uses a WeakVH. CI->replaceAllUsesWith(II); Split->getInstList().pop_front(); // Delete the original call // Update any PHI nodes in the exceptional block to indicate that // there is now a new entry in them. Invoke.addIncomingPHIValuesFor(BB); return false; } return false; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. // If a function returns a struct, make it return // a pointer to the struct. // // Inputs: // M - A reference to the LLVM module to transform // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool StructRet::runOnModule(Module& M) { const llvm::DataLayout targetData(&M); std::vector<Function*> worklist; for (Module::iterator I = M.begin(); I != M.end(); ++I) if (!I->mayBeOverridden()) { if(I->hasAddressTaken()) continue; if(I->getReturnType()->isStructTy()) { worklist.push_back(I); } } while(!worklist.empty()) { Function *F = worklist.back(); worklist.pop_back(); Type *NewArgType = F->getReturnType()->getPointerTo(); // Construct the new Type std::vector<Type*>TP; TP.push_back(NewArgType); for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end(); ii != ee; ++ii) { TP.push_back(ii->getType()); } FunctionType *NFTy = FunctionType::get(F->getReturnType(), TP, F->isVarArg()); // Create the new function body and insert it into the module. Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName(), &M); ValueToValueMapTy ValueMap; Function::arg_iterator NI = NF->arg_begin(); NI->setName("ret"); ++NI; for (Function::arg_iterator II = F->arg_begin(); II != F->arg_end(); ++II, ++NI) { ValueMap[II] = NI; NI->setName(II->getName()); AttributeSet attrs = F->getAttributes().getParamAttributes(II->getArgNo() + 1); if (!attrs.isEmpty()) NI->addAttr(attrs); } // Perform the cloning. SmallVector<ReturnInst*,100> Returns; if (!F->isDeclaration()) CloneFunctionInto(NF, F, ValueMap, false, Returns); std::vector<Value*> fargs; for(Function::arg_iterator ai = NF->arg_begin(), ae= NF->arg_end(); ai != ae; ++ai) { fargs.push_back(ai); } NF->setAttributes(NF->getAttributes().addAttributes( M.getContext(), 0, F->getAttributes().getRetAttributes())); NF->setAttributes(NF->getAttributes().addAttributes( M.getContext(), ~0, F->getAttributes().getFnAttributes())); for (Function::iterator B = NF->begin(), FE = NF->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { ReturnInst * RI = dyn_cast<ReturnInst>(I++); if(!RI) continue; LoadInst *LI = dyn_cast<LoadInst>(RI->getOperand(0)); assert(LI && "Return should be preceded by a load instruction"); IRBuilder<> Builder(RI); Builder.CreateMemCpy(fargs.at(0), LI->getPointerOperand(), targetData.getTypeStoreSize(LI->getType()), targetData.getPrefTypeAlignment(LI->getType())); } } for(Value::use_iterator ui = F->use_begin(), ue = F->use_end(); ui != ue; ) { CallInst *CI = dyn_cast<CallInst>(*ui++); if(!CI) continue; if(CI->getCalledFunction() != F) continue; if(CI->hasByValArgument()) continue; AllocaInst *AllocaNew = new AllocaInst(F->getReturnType(), 0, "", CI); SmallVector<Value*, 8> Args; //this should probably be done in a different manner AttributeSet NewCallPAL=AttributeSet(); // Get the initial attributes of the call AttributeSet CallPAL = CI->getAttributes(); AttributeSet RAttrs = CallPAL.getRetAttributes(); AttributeSet FnAttrs = CallPAL.getFnAttributes(); if (!RAttrs.isEmpty()) NewCallPAL=NewCallPAL.addAttributes(F->getContext(),0, RAttrs); Args.push_back(AllocaNew); for(unsigned j = 0; j < CI->getNumOperands()-1; j++) { Args.push_back(CI->getOperand(j)); // position in the NewCallPAL AttributeSet Attrs = CallPAL.getParamAttributes(j); if (!Attrs.isEmpty()) NewCallPAL=NewCallPAL.addAttributes(F->getContext(),Args.size(), Attrs); } // Create the new attributes vec. if (!FnAttrs.isEmpty()) NewCallPAL=NewCallPAL.addAttributes(F->getContext(),~0, FnAttrs); CallInst *CallI = CallInst::Create(NF, Args, "", CI); CallI->setCallingConv(CI->getCallingConv()); CallI->setAttributes(NewCallPAL); LoadInst *LI = new LoadInst(AllocaNew, "", CI); CI->replaceAllUsesWith(LI); CI->eraseFromParent(); } if(F->use_empty()) F->eraseFromParent(); } return true; }