本文整理汇总了C++中BasicBlock::back方法的典型用法代码示例。如果您正苦于以下问题:C++ BasicBlock::back方法的具体用法?C++ BasicBlock::back怎么用?C++ BasicBlock::back使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BasicBlock
的用法示例。
在下文中一共展示了BasicBlock::back方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: splitCriticalEdge
void PhiElimination::splitCriticalEdge(
IRFunction * func, BasicBlock * block)
{
//if (block->numOfPrecursors() <= 1)
// return;
auto GetInnerBlock = [func, block]
(const std::string &from, const std::string &to) {
BasicBlock *BB = func->createBasicBlock(from + "-" + to);
Goto *go2 = IRContext::create<Goto>(block);
BB->push_back(go2);
BB->addSuccessor(block);
go2->set_parent(BB);
return BB;
};
size_t size = block->numOfPrecursors();
for (auto pre = block->precursor_begin();
pre != block->precursor_end();
++pre) {
BasicBlock *PBB = *pre;
// Check whether split.
if (PBB->numOfSuccessors() <= 1)
continue;
// split it.
BasicBlock *BB = GetInnerBlock(
PBB->getBlockName(), block->getBlockName());
*pre = BB;
PBB->successor_replace(block, BB);
if (PBB->back()->is_goto()) {
Goto *GT = static_cast<Goto*>(PBB->back());
GT->setTarget(BB);
}
else if (PBB->back()->is_branch()) {
Branch *branch = static_cast<Branch*>(PBB->back());
if (branch->then() == block)
branch->setThen(BB);
else
branch->setElse(BB);
}
else {
assert(0 && "impossible");
}
}
}
示例2: runOnLoop
//
// Override the runOnLoop function provided by LoopPass.
// Return true because we intend on modifying the control flow graph.
//
bool LicmPass::runOnLoop(Loop *loop, LPPassManager &LPM) {
unsigned int depth = loop->getLoopDepth();
info = &getAnalysis<LoopInfo>();
cout << "Loop<depth = " << depth << ">" << endl;
// check if there is a preheader
BasicBlock* preheader = loop->getLoopPreheader();
if (!preheader) {
return false;
}
// Run analysis passes on blocks.
const BlockVector& blocks = loop->getBlocks();
BlockStates states = dominance.runOnBlocks(blocks);
showDominators(blocks, states, preheader);
// Cache all the invariants we have found so far.
Invariants invariants;
findInvariants(loop, blocks, states, preheader, invariants);
// Finally, hoist the invariants into the preheader.
// We want to delete this instruction and move it to the end of the
// preheader (before the branch). We can do with with moveBefore.
for (Invariants::iterator I = invariants.begin(), IE = invariants.end();
I != IE; ++I) {
Instruction* end = &(preheader->back());
Instruction* instr = *I;
instr->moveBefore(end);
}
// assume we modified the loop
return true;
};
示例3: identifySuccessorRelation
bool CFGTree::identifySuccessorRelation(BasicBlock *predBB,
BasicBlock *succBB) {
bool identify = false;
BasicBlock *bb = predBB;
while (true) {
Instruction *inst = &(bb->back());
if (inst->getOpcode() == Instruction::Br) {
BranchInst *bi = dyn_cast<BranchInst>(inst);
if (bi->isUnconditional()) {
bb = bi->getSuccessor(0);
if (bb == succBB) {
identify = true;
break;
}
} else {
identify = foundSameBrInstFromCFGTree(inst, root);
break;
}
} else {
if (inst->getOpcode() == Instruction::Ret)
break;
else
assert(false && "Unsupported instruction!");
}
}
return identify;
}
示例4: TransformLongJmpCall
// TransformLongJmpCall - Transform a longjmp call into a call to the
// internal __llvm_sjljeh_throw_longjmp function. It then takes care of
// throwing the exception for us.
void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
{
const Type* SBPTy =
PointerType::getUnqual(Type::getInt8Ty(Inst->getContext()));
// Create the call to "__llvm_sjljeh_throw_longjmp". This takes the
// same parameters as "longjmp", except that the buffer is cast to a
// char*. It returns "void", so it doesn't need to replace any of
// Inst's uses and doesn't get a name.
CastInst* CI =
new BitCastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst);
SmallVector<Value *, 2> Args;
Args.push_back(CI);
Args.push_back(Inst->getOperand(2));
CallInst::Create(ThrowLongJmp, Args.begin(), Args.end(), "", Inst);
SwitchValuePair& SVP = SwitchValMap[Inst->getParent()->getParent()];
// If the function has a setjmp call in it (they are transformed first)
// we should branch to the basic block that determines if this longjmp
// is applicable here. Otherwise, issue an unwind.
if (SVP.first)
BranchInst::Create(SVP.first->getParent(), Inst);
else
new UnwindInst(Inst->getContext(), Inst);
// Remove all insts after the branch/unwind inst. Go from back to front to
// avoid replaceAllUsesWith if possible.
BasicBlock *BB = Inst->getParent();
Instruction *Removed;
do {
Removed = &BB->back();
// If the removed instructions have any users, replace them now.
if (!Removed->use_empty())
Removed->replaceAllUsesWith(UndefValue::get(Removed->getType()));
Removed->eraseFromParent();
} while (Removed != Inst);
++LongJmpsTransformed;
}
示例5: canBasicBlockModify
/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the location Loc.
///
bool AAResults::canBasicBlockModify(const BasicBlock &BB,
const MemoryLocation &Loc) {
return canInstructionRangeModRef(BB.front(), BB.back(), Loc, MRI_Mod);
}
示例6: runOnModule
bool FuncAddrTaken::runOnModule(Module &M) {
bool Changed = false;
// add declaration of function __patch_at
// declare void @__patch_at(void)
FunctionType *FT = FunctionType::get(Type::getVoidTy(M.getContext()),
false);
Function* PatchAt = Function::Create(FT, Function::ExternalLinkage, "__patch_at", &M);
if (PatchAt->getName() != "__patch_at") {
PatchAt->eraseFromParent();
return false;
}
Changed = true;
// Simple optimization so that no function address will be taken twice
// in the same basic block.
std::map<BasicBlock*, std::set<std::string> > UniqPatchAt;
// before each store instruction that manipulates a function, create a call
// to __patch_at
for (auto F = M.getFunctionList().begin(); F != M.getFunctionList().end(); F++) {
for (auto BB = F->begin(); BB != F->end(); BB++) {
for (auto MI = BB->begin(); MI != BB->end(); MI++) {
if (isa<StoreInst>(MI)) {
// check if the store inst moves a function to a variable
Value *V = InnerMost(cast<StoreInst>(MI)->getValueOperand());
addPatchAt(M, FT, V, MI, UniqPatchAt);
if (isa<ConstantVector>(V)) {
std::set<Value*> patched;
for (unsigned i = 0; i < cast<ConstantVector>(V)->getNumOperands(); i++) {
Value *VV = InnerMost(cast<ConstantVector>(V)->getOperand(i));
if (patched.find(VV) == patched.end()) {
addPatchAt(M, FT, VV, MI, UniqPatchAt);
patched.insert(VV);
}
}
} else if (isa<ConstantStruct>(V)) {
std::set<Value*> patched;
for (unsigned i = 0; i < cast<ConstantStruct>(V)->getNumOperands(); i++) {
Value *VV = InnerMost(cast<ConstantStruct>(V)->getOperand(i));
if (patched.find(VV) == patched.end()) {
addPatchAt(M, FT, VV, MI, UniqPatchAt);
patched.insert(VV);
}
}
} else if (isa<ConstantArray>(V)) {
std::set<Value*> patched;
for (unsigned i = 0; i < cast<ConstantArray>(V)->getNumOperands(); i++) {
Value *VV = InnerMost(cast<ConstantArray>(V)->getOperand(i));
if (patched.find(VV) == patched.end()) {
addPatchAt(M, FT, VV, MI, UniqPatchAt);
patched.insert(VV);
}
}
}
} else if (isa<SelectInst>(MI)) {
Value *V = InnerMost(cast<SelectInst>(MI)->getTrueValue());
addPatchAt(M, FT, V, MI, UniqPatchAt);
V = InnerMost(cast<SelectInst>(MI)->getFalseValue());
addPatchAt(M, FT, V, MI, UniqPatchAt);
} else if (isa<CallInst>(MI)) {
CallInst* CI = cast<CallInst>(MI);
for (unsigned i = 0; i < CI->getNumArgOperands(); i++) {
Value *V = InnerMost(CI->getArgOperand(i));
addPatchAt(M, FT, V, MI, UniqPatchAt);
}
} else if (isa<InvokeInst>(MI)) {
InvokeInst* CI = cast<InvokeInst>(MI);
for (unsigned i = 0; i < CI->getNumArgOperands(); i++) {
Value *V = InnerMost(CI->getArgOperand(i));
addPatchAt(M, FT, V, MI, UniqPatchAt);
}
} else if (isa<ReturnInst>(MI)) {
Value *V = cast<ReturnInst>(MI)->getReturnValue();
if (V) {
V = InnerMost(V);
addPatchAt(M, FT, V, MI, UniqPatchAt);
}
} else if (isa<PHINode>(MI)) {
for (unsigned i = 0; i < cast<PHINode>(MI)->getNumIncomingValues(); i++) {
Value *V = InnerMost(cast<PHINode>(MI)->getIncomingValue(i));
BasicBlock* BB = cast<PHINode>(MI)->getIncomingBlock(i);
// right before the last (maybe terminator) instruction.
addPatchAt(M, FT, V, &(BB->back()), UniqPatchAt);
}
}
}
}
}
// TODO: separate the following virtual table traversal code into another pass
for (auto G = M.getGlobalList().begin(); G != M.getGlobalList().end(); G++) {
if (isa<GlobalVariable>(G) &&
cast<GlobalVariable>(G)->hasInitializer()) {
const GlobalVariable *GV = cast<GlobalVariable>(G);
const Constant *C = GV->getInitializer();
if (GV->hasName() && isa<ConstantArray>(C) && GV->getName().startswith("_ZTV")) {
std::string VTName = CXXDemangledName(GV->getName().data());
if (VTName.size() && VTName.find("vtable") == 0) {
//llvm::errs() << VTName << "\n";
VTName = VTName.substr(11); // get pass "vtable for "
//.........这里部分代码省略.........
示例7: canBasicBlockModify
/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
const Location &Loc) {
return canInstructionRangeModify(BB.front(), BB.back(), Loc);
}
示例8: runOnFunction
bool ObjCARCContract::runOnFunction(Function &F) {
if (!EnableARCOpts)
return false;
// If nothing in the Module uses ARC, don't do anything.
if (!Run)
return false;
Changed = false;
AA = &getAnalysis<AliasAnalysis>();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
PA.setAA(&getAnalysis<AliasAnalysis>());
DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
// Track whether it's ok to mark objc_storeStrong calls with the "tail"
// keyword. Be conservative if the function has variadic arguments.
// It seems that functions which "return twice" are also unsafe for the
// "tail" argument, because they are setjmp, which could need to
// return to an earlier stack state.
bool TailOkForStoreStrongs =
!F.isVarArg() && !F.callsFunctionThatReturnsTwice();
// For ObjC library calls which return their argument, replace uses of the
// argument with uses of the call return value, if it dominates the use. This
// reduces register pressure.
SmallPtrSet<Instruction *, 4> DependingInstructions;
SmallPtrSet<const BasicBlock *, 4> Visited;
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
Instruction *Inst = &*I++;
DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
// First try to peephole Inst. If there is nothing further we can do in
// terms of undoing objc-arc-expand, process the next inst.
if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited,
TailOkForStoreStrongs))
continue;
// Otherwise, try to undo objc-arc-expand.
// Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
// and such; to do the replacement, the argument must have type i8*.
Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
// TODO: Change this to a do-while.
for (;;) {
// If we're compiling bugpointed code, don't get in trouble.
if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
break;
// Look through the uses of the pointer.
for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
UI != UE; ) {
// Increment UI now, because we may unlink its element.
Use &U = *UI++;
unsigned OperandNo = U.getOperandNo();
// If the call's return value dominates a use of the call's argument
// value, rewrite the use to use the return value. We check for
// reachability here because an unreachable call is considered to
// trivially dominate itself, which would lead us to rewriting its
// argument in terms of its return value, which would lead to
// infinite loops in GetArgRCIdentityRoot.
if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) {
Changed = true;
Instruction *Replacement = Inst;
Type *UseTy = U.get()->getType();
if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
// For PHI nodes, insert the bitcast in the predecessor block.
unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
BasicBlock *BB = PHI->getIncomingBlock(ValNo);
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "",
&BB->back());
// While we're here, rewrite all edges for this PHI, rather
// than just one use at a time, to minimize the number of
// bitcasts we emit.
for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
if (PHI->getIncomingBlock(i) == BB) {
// Keep the UI iterator valid.
if (UI != UE &&
&PHI->getOperandUse(
PHINode::getOperandNumForIncomingValue(i)) == &*UI)
++UI;
PHI->setIncomingValue(i, Replacement);
}
} else {
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "",
cast<Instruction>(U.getUser()));
U.set(Replacement);
}
}
}
// If Arg is a no-op casted pointer, strip one level of casts and iterate.
if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
Arg = BI->getOperand(0);
else if (isa<GEPOperator>(Arg) &&
//.........这里部分代码省略.........
示例9: cs
//.........这里部分代码省略.........
if(multithreadedFunctionMap[f.getName().str()]){
/// If so, the current callee also becomes multithreaded
multithreadedFunctionMap[calledFunc->getName().str()] = true;
}
#undef DEBUG_TYPE
#define DEBUG_TYPE "strator-parval"
/// We pass some values to the called function, updating flow sensitive value map
CallSite cs(const_cast<CallInst*>(callInst));
Function::arg_iterator calleeIt;
CallSite::arg_iterator callerIt;
if(atThreadCreationFunction) {
/// this is only supported for pthread right now
assert(cs.arg_size() == 4 && "pthread_create should have 4 operands!");
assert(calledFunc->arg_size() == 1 && "pthread thread worker function should have 1 operand");
DEBUG(errs() << *calledFunc->arg_begin() << " = " << *cs.getArgument(3) << "\n");
parentValue[calledFunc->arg_begin()] = cs.getArgument(3);
}else{
for (callerIt = cs.arg_begin(), calleeIt = calledFunc->arg_begin();
callerIt != cs.arg_end() && calleeIt != calledFunc->arg_end();
callerIt++, calleeIt++){
DEBUG(errs() << *calleeIt << " = " << *(callerIt->get()) << "\n");
parentValue[calleeIt] = callerIt->get();
}
}
set<StratorWorker::LockSet>& functionLockSets = traverseFunction(*calledFunc, lockSet);
/// Maybe the called function was multi threaded: If so, the caller becomes multi
/// threaded from this point on if the following two lines are uncommented.
/// However, this support adds a large number of false positives
/*
if(multithreadedFunctionMap[calledFunc->getName().str()])
multithreadedFunctionMap[f.getName().str()] = true;
*/
/// arguments of callee are no longer valid, updating flow sensitive value map
for (calleeIt = calledFunc->arg_begin(); calleeIt != calledFunc->arg_end(); calleeIt++){
parentValue.erase(calleeIt);
}
workingList->insert(workingList->begin(), functionLockSets.begin(), functionLockSets.end());
}
} else {
/// call is not resolved, process the lockset at hand as the working set
workingList->insert(workingList->begin(), lockSet);
}
}
/// TODO: We can leverage the llvm function onlyreadsmemory maybe? At least look at the code
if(inst->getOpcode() == Instruction::Load || inst->getOpcode() == Instruction::Store){
detectRaces(*inst, (inst->getOpcode() == Instruction::Store), lockSet);
}
/// If this is the last instruction of the current BB
/// it means from here we have successor nodes in the control flow.
set<StratorWorker::LockSet>* returnSet = new set<StratorWorker::LockSet>();
BasicBlock* bb = const_cast<BasicBlock*>(inst->getParent());
/// TODO: try to check for terminator instruction here
vector<StratorWorker::LockSet>::iterator workingListLockset;
if(workingList->size() > 0){
if(&(bb->back()) == &(*inst)){
for(workingListLockset = workingList->begin();
workingListLockset != workingList->end(); ++workingListLockset)
for(succ_iterator child = succ_begin(bb), end = succ_end(bb);
child != end; ++child){
BasicBlock::iterator firstInstr = child->begin();
set<Strator::StratorWorker::LockSet>& statementLockSets = traverseStatement(f, firstInstr, entryLockSet, *workingListLockset);
returnSet->insert(statementLockSets.begin(), statementLockSets.end());
}
} else{
/// not the last instruction, simply instruction pointer to the next instruction
BasicBlock::const_iterator nextInst = inst;
++nextInst;
for(workingListLockset = workingList->begin();
workingListLockset != workingList->end(); ++workingListLockset){
set<Strator::StratorWorker::LockSet>& statementLockSets = traverseStatement(f, nextInst, entryLockSet, *workingListLockset);
returnSet->insert(statementLockSets.begin(), statementLockSets.end());
}
}
} else{
if(&(bb->back()) == &(*inst)){
for(succ_iterator child = succ_begin(bb), end = succ_end(bb);
child != end; ++child){
BasicBlock::iterator firstInstr = child->begin();
set<LockSet>& statementLockSets = traverseStatement(f, firstInstr, entryLockSet, lockSet);
returnSet->insert(statementLockSets.begin(), statementLockSets.end());
}
} else{
BasicBlock::const_iterator nextInst = inst;
++nextInst;
set<Strator::StratorWorker::LockSet>& statementLockSets = traverseStatement(f, nextInst, entryLockSet, lockSet);
returnSet->insert(statementLockSets.begin(), statementLockSets.end());
}
}
return *returnSet;
}
示例10: runOnFunction
//.........这里部分代码省略.........
CI->eraseFromParent();
}
continue;
}
case IC_Release:
ContractRelease(Inst, I);
continue;
case IC_User:
// Be conservative if the function has any alloca instructions.
// Technically we only care about escaping alloca instructions,
// but this is sufficient to handle some interesting cases.
if (isa<AllocaInst>(Inst))
TailOkForStoreStrongs = false;
continue;
case IC_IntrinsicUser:
// Remove calls to @clang.arc.use(...).
Inst->eraseFromParent();
continue;
default:
continue;
}
DEBUG(dbgs() << "ObjCARCContract: Finished List.\n\n");
// Don't use GetObjCArg because we don't want to look through bitcasts
// and such; to do the replacement, the argument must have type i8*.
const Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
for (;;) {
// If we're compiling bugpointed code, don't get in trouble.
if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
break;
// Look through the uses of the pointer.
for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
UI != UE; ) {
Use &U = UI.getUse();
unsigned OperandNo = UI.getOperandNo();
++UI; // Increment UI now, because we may unlink its element.
// If the call's return value dominates a use of the call's argument
// value, rewrite the use to use the return value. We check for
// reachability here because an unreachable call is considered to
// trivially dominate itself, which would lead us to rewriting its
// argument in terms of its return value, which would lead to
// infinite loops in GetObjCArg.
if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) {
Changed = true;
Instruction *Replacement = Inst;
Type *UseTy = U.get()->getType();
if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
// For PHI nodes, insert the bitcast in the predecessor block.
unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
BasicBlock *BB = PHI->getIncomingBlock(ValNo);
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "",
&BB->back());
// While we're here, rewrite all edges for this PHI, rather
// than just one use at a time, to minimize the number of
// bitcasts we emit.
for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
if (PHI->getIncomingBlock(i) == BB) {
// Keep the UI iterator valid.
if (&PHI->getOperandUse(
PHINode::getOperandNumForIncomingValue(i)) ==
&UI.getUse())
++UI;
PHI->setIncomingValue(i, Replacement);
}
} else {
if (Replacement->getType() != UseTy)
Replacement = new BitCastInst(Replacement, UseTy, "",
cast<Instruction>(U.getUser()));
U.set(Replacement);
}
}
}
// If Arg is a no-op casted pointer, strip one level of casts and iterate.
if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
Arg = BI->getOperand(0);
else if (isa<GEPOperator>(Arg) &&
cast<GEPOperator>(Arg)->hasAllZeroIndices())
Arg = cast<GEPOperator>(Arg)->getPointerOperand();
else if (isa<GlobalAlias>(Arg) &&
!cast<GlobalAlias>(Arg)->mayBeOverridden())
Arg = cast<GlobalAlias>(Arg)->getAliasee();
else
break;
}
}
// If this function has no escaping allocas or suspicious vararg usage,
// objc_storeStrong calls can be marked with the "tail" keyword.
if (TailOkForStoreStrongs)
for (SmallPtrSet<CallInst *, 8>::iterator I = StoreStrongCalls.begin(),
E = StoreStrongCalls.end(); I != E; ++I)
(*I)->setTailCall();
StoreStrongCalls.clear();
return Changed;
}
示例11: runOnFunction
bool ObjCARCContract::runOnFunction(Function &F) {
if (!EnableARCOpts)
return false;
// If nothing in the Module uses ARC, don't do anything.
if (!Run)
return false;
Changed = false;
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
PA.setAA(&getAnalysis<AAResultsWrapperPass>().getAAResults());
DenseMap<BasicBlock *, ColorVector> BlockColors;
if (F.hasPersonalityFn() &&
isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
BlockColors = colorEHFunclets(F);
LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
// Track whether it's ok to mark objc_storeStrong calls with the "tail"
// keyword. Be conservative if the function has variadic arguments.
// It seems that functions which "return twice" are also unsafe for the
// "tail" argument, because they are setjmp, which could need to
// return to an earlier stack state.
bool TailOkForStoreStrongs =
!F.isVarArg() && !F.callsFunctionThatReturnsTwice();
// For ObjC library calls which return their argument, replace uses of the
// argument with uses of the call return value, if it dominates the use. This
// reduces register pressure.
SmallPtrSet<Instruction *, 4> DependingInstructions;
SmallPtrSet<const BasicBlock *, 4> Visited;
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
Instruction *Inst = &*I++;
LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
// First try to peephole Inst. If there is nothing further we can do in
// terms of undoing objc-arc-expand, process the next inst.
if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited,
TailOkForStoreStrongs, BlockColors))
continue;
// Otherwise, try to undo objc-arc-expand.
// Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
// and such; to do the replacement, the argument must have type i8*.
// Function for replacing uses of Arg dominated by Inst.
auto ReplaceArgUses = [Inst, this](Value *Arg) {
// If we're compiling bugpointed code, don't get in trouble.
if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
return;
// Look through the uses of the pointer.
for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
UI != UE; ) {
// Increment UI now, because we may unlink its element.
Use &U = *UI++;
unsigned OperandNo = U.getOperandNo();
// If the call's return value dominates a use of the call's argument
// value, rewrite the use to use the return value. We check for
// reachability here because an unreachable call is considered to
// trivially dominate itself, which would lead us to rewriting its
// argument in terms of its return value, which would lead to
// infinite loops in GetArgRCIdentityRoot.
if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
continue;
Changed = true;
Instruction *Replacement = Inst;
Type *UseTy = U.get()->getType();
if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
// For PHI nodes, insert the bitcast in the predecessor block.
unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
if (Replacement->getType() != UseTy) {
// A catchswitch is both a pad and a terminator, meaning a basic
// block with a catchswitch has no insertion point. Keep going up
// the dominator tree until we find a non-catchswitch.
BasicBlock *InsertBB = IncomingBB;
while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHI())) {
InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
}
assert(DT->dominates(Inst, &InsertBB->back()) &&
"Invalid insertion point for bitcast");
Replacement =
new BitCastInst(Replacement, UseTy, "", &InsertBB->back());
}
// While we're here, rewrite all edges for this PHI, rather
// than just one use at a time, to minimize the number of
// bitcasts we emit.
for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
if (PHI->getIncomingBlock(i) == IncomingBB) {
// Keep the UI iterator valid.
//.........这里部分代码省略.........
示例12: canBasicBlockModify
/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
const Value *Ptr, unsigned Size) {
return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size);
}
示例13: Formula
std::vector<SetOfFormulasPtr>
FaultLocalization::allDiagnosis(Formula *TF,
std::vector<ProgramTrace*> traces,
YicesSolver *yices) {
std::vector<SetOfFormulasPtr> MCSes;
int progress = 0;
int total = traces.size();
// Working formula
Formula *WF = new Formula(TF);
// For each E in WF, E tagged as soft do
unsigned z = 0;
std::vector<BoolVarExprPtr> AV;
std::map<BoolVarExprPtr, ExprPtr> AVMap;
std::vector<ExprPtr> clauses = WF->getExprs();
for(ExprPtr e : clauses) {
if (e->isSoft()) {
// AI is a new auxiliary var. created
std::ostringstream oss;
oss << z++;
BoolVarExprPtr ai = Expression::mkBoolVar("a_"+oss.str());
ai->setInstruction(e->getInstruction());
ai->setLine(e->getLine());
AV.push_back(ai);
AVMap[ai] = e;
ExprPtr notai = Expression::mkNot(ai);
//notai->setWeight(e->getWeight());
notai->setLine(e->getLine());
notai->setSoft();
WF->add(notai);
// Remove E and add EA as hard
ExprPtr ea = Expression::mkOr(e, ai);
WF->remove(e);
ea->setHard();
WF->add(ea);
}
}
if (AV.empty()) {
delete WF;
std::cout << "No MaxSMT solution!\n";
if (options->verbose()) {
std::cout << "==============================================\n";
}
return MCSes;
}
yices->init();
yices->addToContext(WF);
for(ProgramTrace *E : traces) {
if (options->verbose()) {
displayProgressBar(progress, total);
}
// At this point there is only WF in the context
yices->push();
// Assert as hard the error-inducing input formula
ExprPtr eiExpr = E->getProgramInputsFormula(TF);
eiExpr->setHard();
yices->addToContext(eiExpr);
if (options->dbgMsg()) {
std::cout << "-- Error-inducing Input: ";
eiExpr->dump();
std::cout << std::endl;
}
// Assert as hard the golden output (if any)
// (= return_var golden_output)
Value *goldenOutput = E->getExpectedOutput();
if (goldenOutput) {
BasicBlock *lastBB = &targetFun->back();
Instruction *lastInst = &lastBB->back();
if (ReturnInst *ret= dyn_cast<ReturnInst>(lastInst)) {
Value *retVal = ret->getReturnValue();
if (retVal) {
ExprPtr retExpr = Expression::getExprFromValue(retVal);
ExprPtr goExpr = Expression::getExprFromValue(goldenOutput);
ExprPtr eqExpr = Expression::mkEq(retExpr, goExpr);
eqExpr->setHard();
yices->addToContext(eqExpr);
if (options->dbgMsg()) {
std::cout << "-- Golden ouput: ";
eqExpr->dump();
std::cout << std::endl;
}
}
}
}
// Compute a MCS
SetOfFormulasPtr M = allMinMCS(yices, AV, AVMap);
if (!M->empty()) {
SetOfFormulasPtr M2 = avToClauses(M, AVMap);
MCSes.push_back(M2);
if (options->printMCS()) {
std::cout << "\n" << M2 << "\n" << std::endl;
}
} else {
//if (options->verbose() || options->dbgMsg()) {
std::cout << "Empty MCS!\n";
//}
}
// Backtrack to the point where there
// was no Pre/Post-conditions in the formula
yices->pop();
// Progress bar
//.........这里部分代码省略.........
示例14: findExceptionInBlock
/// [LIBUNWIND] Find the (possibly absent) call to @llvm.eh.selector
/// in the given landing pad. In principle, llvm.eh.exception is
/// required to be in the landing pad; in practice, SplitCriticalEdge
/// can break that invariant, and then inlining can break it further.
/// There's a real need for a reliable solution here, but until that
/// happens, we have some fragile workarounds here.
static EHSelectorInst *findSelectorForLandingPad(BasicBlock *lpad) {
// Look for an exception call in the actual landing pad.
EHExceptionInst *exn = findExceptionInBlock(lpad);
if (exn) return findSelectorForException(exn);
// Okay, if that failed, look for one in an obvious successor. If
// we find one, we'll fix the IR by moving things back to the
// landing pad.
bool dominates = true; // does the lpad dominate the exn call
BasicBlock *nonDominated = 0; // if not, the first non-dominated block
BasicBlock *lastDominated = 0; // and the block which branched to it
BasicBlock *exnBlock = lpad;
// We need to protect against lpads that lead into infinite loops.
SmallPtrSet<BasicBlock*,4> visited;
visited.insert(exnBlock);
do {
// We're not going to apply this hack to anything more complicated
// than a series of unconditional branches, so if the block
// doesn't terminate in an unconditional branch, just fail. More
// complicated cases can arise when, say, sinking a call into a
// split unwind edge and then inlining it; but that can do almost
// *anything* to the CFG, including leaving the selector
// completely unreachable. The only way to fix that properly is
// to (1) prohibit transforms which move the exception or selector
// values away from the landing pad, e.g. by producing them with
// instructions that are pinned to an edge like a phi, or
// producing them with not-really-instructions, and (2) making
// transforms which split edges deal with that.
BranchInst *branch = dyn_cast<BranchInst>(&exnBlock->back());
if (!branch || branch->isConditional()) return 0;
BasicBlock *successor = branch->getSuccessor(0);
// Fail if we found an infinite loop.
if (!visited.insert(successor)) return 0;
// If the successor isn't dominated by exnBlock:
if (!successor->getSinglePredecessor()) {
// We don't want to have to deal with threading the exception
// through multiple levels of phi, so give up if we've already
// followed a non-dominating edge.
if (!dominates) return 0;
// Otherwise, remember this as a non-dominating edge.
dominates = false;
nonDominated = successor;
lastDominated = exnBlock;
}
exnBlock = successor;
// Can we stop here?
exn = findExceptionInBlock(exnBlock);
} while (!exn);
// Look for a selector call for the exception we found.
EHSelectorInst *selector = findSelectorForException(exn);
if (!selector) return 0;
// The easy case is when the landing pad still dominates the
// exception call, in which case we can just move both calls back to
// the landing pad.
if (dominates) {
selector->moveBefore(lpad->getFirstNonPHI());
exn->moveBefore(selector);
return selector;
}
// Otherwise, we have to split at the first non-dominating block.
// The CFG looks basically like this:
// lpad:
// phis_0
// insnsAndBranches_1
// br label %nonDominated
// nonDominated:
// phis_2
// insns_3
// %exn = call i8* @llvm.eh.exception()
// insnsAndBranches_4
// %selector = call @llvm.eh.selector(i8* %exn, ...
// We need to turn this into:
// lpad:
// phis_0
// %exn0 = call i8* @llvm.eh.exception()
// %selector0 = call @llvm.eh.selector(i8* %exn0, ...
// insnsAndBranches_1
// br label %split // from lastDominated
// nonDominated:
// phis_2 (without edge from lastDominated)
// %exn1 = call i8* @llvm.eh.exception()
//.........这里部分代码省略.........
示例15: visitLoop
bool LoopRegionDump::visitLoop(Loop *L, Module *mod) {
// Ensure we are working only on outermost loops
if (L->getLoopDepth() > 1)
return false;
// Get the function we are in
Function *currFunc = L->getHeader()->getParent();
// Are we in an isolated Region
std::size_t found = currFunc->getName().find("__cere__");
if (found == std::string::npos)
return false;
// If we want to dump a particular region, look if it's this one
if (!GlobalDump && RegionToDump != currFunc->getName()) {
return false;
} else if (ReadFromFile) {
if (!(std::find(RegionsToDump.begin(), RegionsToDump.end(),
currFunc->getName()) != RegionsToDump.end()))
return false;
}
// Create dump function
Function *func_dump = mod->getFunction("dump");
if (!func_dump) { // If function "dump" not found, creates it
FunctionType *DumpFuncTy = createDumpFunctionType(mod);
func_dump =
Function::Create(DumpFuncTy, GlobalValue::ExternalLinkage, "dump", mod);
}
// Create after_dump function
Function *func_after_dump = mod->getFunction("after_dump");
if (!func_after_dump) { // If function "after_dump" not found, creates it
// Create a void type
std::vector<Type *> FuncTy_12_args;
FunctionType *AfterDumpFuncTy = FunctionType::get(
/*Result=*/Type::getVoidTy(mod->getContext()),
/*Params=*/FuncTy_12_args,
/*isVarArg=*/false);
func_after_dump = Function::Create(
AfterDumpFuncTy, GlobalValue::ExternalLinkage, "after_dump", mod);
}
// Get predecessor loop basic block
BasicBlock *PredBB = L->getLoopPredecessor();
// Get all exit blocks
SmallVector<BasicBlock *, 8> exitblocks;
L->getExitBlocks(exitblocks);
if (PredBB == NULL || exitblocks.size() == 0)
return false;
++RegionCounter;
// Create arguments for the dump function
std::vector<Value *> funcParameter =
createDumpFunctionParameters(mod, currFunc, PredBB, InvocationToDump);
// Call dump function just before the region
CallInst::Create(func_dump, funcParameter, "", &PredBB->back());
// Call after dump in each exit blocks
for (SmallVectorImpl<BasicBlock *>::iterator I = exitblocks.begin(),
E = exitblocks.end();
I != E; ++I) {
CallInst::Create(func_after_dump, "", &(*I)->front());
}
return true;
}