本文整理汇总了C++中CallInst::getNextNode方法的典型用法代码示例。如果您正苦于以下问题:C++ CallInst::getNextNode方法的具体用法?C++ CallInst::getNextNode怎么用?C++ CallInst::getNextNode使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CallInst
的用法示例。
在下文中一共展示了CallInst::getNextNode方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
/// 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
//.........这里部分代码省略.........
示例2: createCallSite
CallInst* ArgumentRecovery::createCallSite(TargetInfo& targetInfo, const CallInformation& ci, Value& callee, Value& callerRegisters, Instruction& insertionPoint)
{
LLVMContext& ctx = insertionPoint.getContext();
unsigned pointerSize = targetInfo.getPointerSize() * CHAR_BIT;
Type* integer = Type::getIntNTy(ctx, pointerSize);
Type* integerPtr = Type::getIntNPtrTy(ctx, pointerSize, 1);
// Create GEPs in caller for each value that we need.
// Load SP first since we might need it.
auto spPtr = targetInfo.getRegister(&callerRegisters, *targetInfo.getStackPointer());
spPtr->insertBefore(&insertionPoint);
auto spValue = new LoadInst(spPtr, "sp", &insertionPoint);
// Fix parameters
SmallVector<Value*, 8> arguments;
for (const auto& vi : ci.parameters())
{
if (vi.type == ValueInformation::IntegerRegister)
{
auto registerPtr = targetInfo.getRegister(&callerRegisters, *vi.registerInfo);
registerPtr->insertBefore(&insertionPoint);
auto registerValue = new LoadInst(registerPtr, vi.registerInfo->name, &insertionPoint);
arguments.push_back(registerValue);
}
else if (vi.type == ValueInformation::Stack)
{
// assume one pointer-sized word
auto offsetConstant = ConstantInt::get(integer, vi.frameBaseOffset);
auto offset = BinaryOperator::Create(BinaryOperator::Add, spValue, offsetConstant, "", &insertionPoint);
auto casted = new IntToPtrInst(offset, integerPtr, "", &insertionPoint);
auto loaded = new LoadInst(casted, "", &insertionPoint);
arguments.push_back(loaded);
}
else
{
llvm_unreachable("not implemented");
}
}
CallInst* newCall = CallInst::Create(&callee, arguments, "", &insertionPoint);
// Fix return value(s)
unsigned i = 0;
Instruction* returnInsertionPoint = newCall->getNextNode();
for (const auto& vi : ci.returns())
{
if (vi.type == ValueInformation::IntegerRegister)
{
Value* registerValue = ci.returns_size() == 1
? static_cast<Value*>(newCall)
: ExtractValueInst::Create(newCall, {i}, vi.registerInfo->name, returnInsertionPoint);
auto registerPtr = targetInfo.getRegister(&callerRegisters, *vi.registerInfo);
registerPtr->insertBefore(returnInsertionPoint);
new StoreInst(registerValue, registerPtr, returnInsertionPoint);
}
else
{
llvm_unreachable("not implemented");
}
i++;
}
return newCall;
}
示例3: Create
/// \brief Recursively handle the condition leading to a loop
Value *SIAnnotateControlFlow::handleLoopCondition(
Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term,
SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions) {
// Only search through PHI nodes which are inside the loop. If we try this
// with PHI nodes that are outside of the loop, we end up inserting new PHI
// nodes outside of the loop which depend on values defined inside the loop.
// This will break the module with
// 'Instruction does not dominate all users!' errors.
PHINode *Phi = nullptr;
if ((Phi = dyn_cast<PHINode>(Cond)) && L->contains(Phi)) {
BasicBlock *Parent = Phi->getParent();
PHINode *NewPhi = PHINode::Create(Int64, 0, "loop.phi", &Parent->front());
Value *Ret = NewPhi;
// Handle all non-constant incoming values first
for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
Value *Incoming = Phi->getIncomingValue(i);
BasicBlock *From = Phi->getIncomingBlock(i);
if (isa<ConstantInt>(Incoming)) {
NewPhi->addIncoming(Broken, From);
continue;
}
Phi->setIncomingValue(i, BoolFalse);
Value *PhiArg = handleLoopCondition(Incoming, Broken, L,
Term, LoopPhiConditions);
NewPhi->addIncoming(PhiArg, From);
}
BasicBlock *IDom = DT->getNode(Parent)->getIDom()->getBlock();
for (unsigned i = 0, e = Phi->getNumIncomingValues(); i != e; ++i) {
Value *Incoming = Phi->getIncomingValue(i);
if (Incoming != BoolTrue)
continue;
BasicBlock *From = Phi->getIncomingBlock(i);
if (From == IDom) {
// We're in the following situation:
// IDom/From
// | \
// | If-block
// | /
// Parent
// where we want to break out of the loop if the If-block is not taken.
// Due to the depth-first traversal, there should be an end.cf
// intrinsic in Parent, and we insert an else.break before it.
//
// Note that the end.cf need not be the first non-phi instruction
// of parent, particularly when we're dealing with a multi-level
// break, but it should occur within a group of intrinsic calls
// at the beginning of the block.
CallInst *OldEnd = dyn_cast<CallInst>(Parent->getFirstInsertionPt());
while (OldEnd && OldEnd->getCalledFunction() != EndCf)
OldEnd = dyn_cast<CallInst>(OldEnd->getNextNode());
if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
continue;
}
}
TerminatorInst *Insert = From->getTerminator();
Value *PhiArg = CallInst::Create(Break, Broken, "", Insert);
NewPhi->setIncomingValue(i, PhiArg);
}
LoopPhiConditions.push_back(WeakTrackingVH(Phi));
return Ret;
}
if (Instruction *Inst = dyn_cast<Instruction>(Cond)) {
BasicBlock *Parent = Inst->getParent();
Instruction *Insert;
if (L->contains(Inst)) {
Insert = Parent->getTerminator();
} else {
Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime();
}
Value *Args[] = { Cond, Broken };
return CallInst::Create(IfBreak, Args, "", Insert);
}
// Insert IfBreak in the loop header TERM for constant COND other than true.
if (isa<Constant>(Cond)) {
Instruction *Insert = Cond == BoolTrue ?
Term : L->getHeader()->getTerminator();
Value *Args[] = { Cond, Broken };
return CallInst::Create(IfBreak, Args, "", Insert);
}
llvm_unreachable("Unhandled loop condition!");
}
示例4: rewriteConstructorImplementation
void DuettoNativeRewriter::rewriteConstructorImplementation(Module& M, Function& F)
{
//Copy the code in a function with the right signature
Function* newFunc=getReturningConstructor(M, &F);
if(!newFunc->empty())
return;
//Visit each instruction and take note of the ones that needs to be replaced
Function::const_iterator B=F.begin();
Function::const_iterator BE=F.end();
ValueToValueMapTy valueMap;
CallInst* lowerConstructor = NULL;
const CallInst* oldLowerConstructor = NULL;
for(;B!=BE;++B)
{
BasicBlock::const_iterator I=B->begin();
BasicBlock::const_iterator IE=B->end();
for(;I!=IE;++I)
{
if(I->getOpcode()!=Instruction::Call)
continue;
const CallInst* callInst=cast<CallInst>(&(*I));
Function* f=callInst->getCalledFunction();
if(!f)
continue;
const char* startOfType;
const char* endOfType;
if(!DuettoNativeRewriter::isBuiltinConstructor(f->getName().data(), startOfType, endOfType))
continue;
//Check that the constructor is for 'this'
if(callInst->getOperand(0)!=F.arg_begin())
continue;
//If this is another constructor for the same type, change it to a
//returning constructor and use it as the 'this' argument
Function* newFunc = getReturningConstructor(M, f);
llvm::SmallVector<Value*, 4> newArgs;
for(unsigned i=1;i<callInst->getNumArgOperands();i++)
newArgs.push_back(callInst->getArgOperand(i));
lowerConstructor = CallInst::Create(newFunc, newArgs);
oldLowerConstructor = callInst;
break;
}
if(lowerConstructor)
break;
}
//Clone the linkage first
newFunc->setLinkage(F.getLinkage());
Function::arg_iterator origArg=++F.arg_begin();
Function::arg_iterator newArg=newFunc->arg_begin();
valueMap.insert(make_pair(F.arg_begin(), lowerConstructor));
for(unsigned i=1;i<F.arg_size();i++)
{
valueMap.insert(make_pair(&(*origArg), &(*newArg)));
++origArg;
++newArg;
}
SmallVector<ReturnInst*, 4> returns;
CloneFunctionInto(newFunc, &F, valueMap, false, returns);
//Find the right place to add the base construtor call
assert(lowerConstructor->getNumArgOperands()<=1 && "Native constructors with multiple args are not supported");
Instruction* callPred = NULL;
if (lowerConstructor->getNumArgOperands()==1 && Instruction::classof(lowerConstructor->getArgOperand(0)))
{
//Switch the argument to the one in the new func
lowerConstructor->setArgOperand(0, valueMap[lowerConstructor->getArgOperand(0)]);
callPred = cast<Instruction>(lowerConstructor->getArgOperand(0));
}
else
callPred = &newFunc->getEntryBlock().front();
//Add add it
lowerConstructor->insertAfter(callPred);
//Override the returs values
for(unsigned i=0;i<returns.size();i++)
{
Instruction* newInst = ReturnInst::Create(M.getContext(),lowerConstructor);
newInst->insertBefore(returns[i]);
returns[i]->removeFromParent();
}
//Recursively move all the users of the lower constructor after the call itself
Instruction* insertPoint = lowerConstructor->getNextNode();
SmallVector<Value*, 4> usersQueue(lowerConstructor->getNumUses());
unsigned int i;
Value::use_iterator it;
for(i=usersQueue.size()-1,it=lowerConstructor->use_begin();it!=lowerConstructor->use_end();++it,i--)
usersQueue[i]=it->getUser();
SmallSet<Instruction*, 4> movedInstructions;
while(!usersQueue.empty())
{
Instruction* cur=dyn_cast<Instruction>(usersQueue.pop_back_val());
if(!cur)
continue;
if(movedInstructions.count(cur))
continue;
movedInstructions.insert(cur);
//.........这里部分代码省略.........