本文整理汇总了C++中basicblock::iterator::getOperand方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::getOperand方法的具体用法?C++ iterator::getOperand怎么用?C++ iterator::getOperand使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类basicblock::iterator
的用法示例。
在下文中一共展示了iterator::getOperand方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1:
bool llvm::ValueCounter::runOnModule(Module& M) {
std::set<Value*> values;
for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){
if (!values.count(Fit)) values.insert(Fit);
for(Function::arg_iterator Arg = Fit->arg_begin(), aEnd = Fit->arg_end(); Arg != aEnd; Arg++) {
if (!values.count(Arg)) values.insert(Arg);
}
for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; BBit++) {
for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; Iit++) {
if (!values.count(Iit)) values.insert(Iit);
for(unsigned int i = 0; i < Iit->getNumOperands(); i++){
if (!values.count(Iit->getOperand(i))) values.insert(Iit->getOperand(i));
}
}
}
}
TotalValues = values.size();
//We don't modify anything, so we must return false;
return false;
}
示例2: runOnModule
bool OvershiftCheckPass::runOnModule(Module &M) {
Function *overshiftCheckFunction = 0;
LLVMContext &ctx = M.getContext();
bool moduleChanged = false;
for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) {
for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) {
for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) {
if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) {
// find all shift instructions
Instruction::BinaryOps opcode = binOp->getOpcode();
if (opcode == Instruction::Shl ||
opcode == Instruction::LShr ||
opcode == Instruction::AShr ) {
std::vector<llvm::Value*> args;
// Determine bit width of first operand
uint64_t bitWidth=i->getOperand(0)->getType()->getScalarSizeInBits();
ConstantInt *bitWidthC = ConstantInt::get(Type::getInt64Ty(ctx),
bitWidth, false);
args.push_back(bitWidthC);
CastInst *shift =
CastInst::CreateIntegerCast(i->getOperand(1),
Type::getInt64Ty(ctx),
false, /* sign doesn't matter */
"int_cast_to_i64",
&*i);
args.push_back(shift);
// Lazily bind the function to avoid always importing it.
if (!overshiftCheckFunction) {
Constant *fc = M.getOrInsertFunction("klee_overshift_check",
Type::getVoidTy(ctx),
Type::getInt64Ty(ctx),
Type::getInt64Ty(ctx),
NULL);
overshiftCheckFunction = cast<Function>(fc);
}
// Inject CallInstr to check if overshifting possible
CallInst *ci =
CallInst::Create(overshiftCheckFunction, args, "", &*i);
// set debug information from binary operand to preserve it
ci->setDebugLoc(binOp->getDebugLoc());
moduleChanged = true;
}
}
}
}
}
return moduleChanged;
}
示例3: promoteConstant
bool ARM64PromoteConstant::runOnFunction(Function &F) {
// Look for instructions using constant vector
// Promote that constant to a global variable.
// Create as few load of this variable as possible and update the uses
// accordingly
bool LocalChange = false;
SmallSet<Constant *, 8> AlreadyChecked;
for (Function::iterator IBB = F.begin(), IEndBB = F.end();
IBB != IEndBB; ++IBB) {
for (BasicBlock::iterator II = IBB->begin(), IEndI = IBB->end();
II != IEndI; ++II) {
// Traverse the operand, looking for constant vectors
// Replace them by a load of a global variable of type constant vector
for (unsigned OpIdx = 0, EndOpIdx = II->getNumOperands();
OpIdx != EndOpIdx; ++OpIdx) {
Constant *Cst = dyn_cast<Constant>(II->getOperand(OpIdx));
// There is no point is promoting global value, they are already global.
// Do not promote constant expression, as they may require some code
// expansion.
if (Cst && !isa<GlobalValue>(Cst) && !isa<ConstantExpr>(Cst) &&
AlreadyChecked.insert(Cst))
LocalChange |= promoteConstant(Cst);
}
}
}
return LocalChange;
}
示例4: X
void IntTest::pbzip2_like(Module &M) {
TestBanner X("pbzip2-like");
vector<StoreInst *> writes;
Function *f_rand = M.getFunction("rand");
assert(f_rand);
Function *f_producer = M.getFunction("_Z8producerPv.SLICER");
assert(f_producer);
// Search along the CFG. We need to make sure reads and writes are in
// a consistent order.
for (Function::iterator bb = f_producer->begin();
bb != f_producer->end(); ++bb) {
for (BasicBlock::iterator ins = bb->begin(); ins != bb->end(); ++ins) {
if (CallInst *ci = dyn_cast<CallInst>(ins)) {
if (ci->getCalledFunction() == f_rand) {
for (BasicBlock::iterator j = bb->begin(); j != bb->end(); ++j) {
if (StoreInst *si = dyn_cast<StoreInst>(j))
writes.push_back(si);
}
}
}
}
}
errs() << "=== writes ===\n";
for (size_t i = 0; i < writes.size(); ++i) {
errs() << *writes[i] << "\n";
}
vector<LoadInst *> reads;
Function *f_consumer = M.getFunction("_Z8consumerPv.SLICER");
assert(f_consumer);
for (Function::iterator bb = f_consumer->begin();
bb != f_consumer->end(); ++bb) {
for (BasicBlock::iterator ins = bb->begin(); ins != bb->end(); ++ins) {
if (ins->getOpcode() == Instruction::Add &&
ins->getType()->isIntegerTy(8)) {
LoadInst *li = dyn_cast<LoadInst>(ins->getOperand(0));
assert(li);
reads.push_back(li);
}
}
}
errs() << "=== reads ===\n";
for (size_t i = 0; i < reads.size(); ++i) {
errs() << *reads[i] << "\n";
}
assert(writes.size() == reads.size());
AliasAnalysis &AA = getAnalysis<AdvancedAlias>();
for (size_t i = 0; i < writes.size(); ++i) {
for (size_t j = i + 1; j < reads.size(); ++j) {
errs() << "i = " << i << ", j = " << j << "... ";
AliasAnalysis::AliasResult res = AA.alias(
writes[i]->getPointerOperand(),
reads[j]->getPointerOperand());
assert(res == AliasAnalysis::NoAlias);
print_pass(errs());
}
}
}
示例5: FindContextVariables
void LowerEmAsyncify::FindContextVariables(AsyncCallEntry & Entry) {
BasicBlock *AfterCallBlock = Entry.AfterCallBlock;
Function & F = *AfterCallBlock->getParent();
// Create a new entry block as if in the callback function
// theck check variables that no longer properly dominate their uses
BasicBlock *EntryBlock = BasicBlock::Create(TheModule->getContext(), "", &F, &F.getEntryBlock());
BranchInst::Create(AfterCallBlock, EntryBlock);
DominatorTreeWrapperPass DTW;
DTW.runOnFunction(F);
DominatorTree& DT = DTW.getDomTree();
// These blocks may be using some values defined at or before AsyncCallBlock
BasicBlockSet Ramifications = FindReachableBlocksFrom(AfterCallBlock);
SmallPtrSet<Value*, 256> ContextVariables;
Values Pending;
// Examine the instructions, find all variables that we need to store in the context
for (BasicBlockSet::iterator RI = Ramifications.begin(), RE = Ramifications.end(); RI != RE; ++RI) {
for (BasicBlock::iterator I = (*RI)->begin(), E = (*RI)->end(); I != E; ++I) {
for (unsigned i = 0, NumOperands = I->getNumOperands(); i < NumOperands; ++i) {
Value *O = I->getOperand(i);
if (Instruction *Inst = dyn_cast<Instruction>(O)) {
if (Inst == Entry.AsyncCallInst) continue; // for the original async call, we will load directly from async return value
if (ContextVariables.count(Inst) != 0) continue; // already examined
if (!DT.dominates(Inst, I->getOperandUse(i))) {
// `I` is using `Inst`, yet `Inst` does not dominate `I` if we arrive directly at AfterCallBlock
// so we need to save `Inst` in the context
ContextVariables.insert(Inst);
Pending.push_back(Inst);
}
} else if (Argument *Arg = dyn_cast<Argument>(O)) {
// count() should be as fast/slow as insert, so just insert here
ContextVariables.insert(Arg);
}
}
}
}
// restore F
EntryBlock->eraseFromParent();
Entry.ContextVariables.clear();
Entry.ContextVariables.reserve(ContextVariables.size());
for (SmallPtrSet<Value*, 256>::iterator I = ContextVariables.begin(), E = ContextVariables.end(); I != E; ++I) {
Entry.ContextVariables.push_back(*I);
}
}
示例6: addDefinedFunctionSymbol
void LTOModule::addDefinedFunctionSymbol(Function* f, Mangler &mangler)
{
// add to list of defined symbols
addDefinedSymbol(f, mangler, true);
// add external symbols referenced by this function.
for (Function::iterator b = f->begin(); b != f->end(); ++b) {
for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) {
for (unsigned count = 0, total = i->getNumOperands();
count != total; ++count) {
findExternalRefs(i->getOperand(count), mangler);
}
}
}
}
示例7: runOnFunction
bool RemoveExtendsPass::runOnFunction(Function& f)
{
CurrentFile::set(__FILE__);
bool changed = false ;
//see if there are any ROCCCNames or ROCCCSizes that caused the extend
for(Function::iterator BB = f.begin(); BB != f.end(); ++BB)
{
begin:
for(BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II)
{
if( dynamic_cast<FPExtInst*>(&*II) or
dynamic_cast<ZExtInst*>(&*II) or
dynamic_cast<SExtInst*>(&*II) or
dynamic_cast<BitCastInst*>(&*II) )
{
INTERNAL_MESSAGE("Attempting to remove uses of " << II->getName() << "\n");
for(Value::use_iterator UI = II->use_begin(); UI != II->use_end(); ++UI)
{
dynamic_cast<Instruction*>(*UI)->replaceUsesOfWith(II, II->getOperand(0));
goto begin;
}
if( II->use_begin() == II->use_end() )
{
II->eraseFromParent();
II = BB->begin();
}
else
{
INTERNAL_ERROR("Extend " << *II << " is still used in " << **II->use_begin() << "!");
assert(0 and "Extend operation still exists!");
}
}
}
}
return changed ;
}
示例8: genMutationFile
void MutationGen::genMutationFile(Function & F){
int index = 0;
for(Function::iterator FI = F.begin(); FI != F.end(); ++FI){
BasicBlock *BB = FI;
#if NEED_LOOP_INFO
bool isLoop = LI->getLoopFor(BB);
#endif
for(BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI, index++){
unsigned opc = BI->getOpcode();
if( !((opc >= 14 && opc <= 31) || opc == 34 || opc == 52 || opc == 55) ){// omit alloca and getelementptr
continue;
}
int idxtmp = index;
#if NEED_LOOP_INFO
if(isLoop){
assert(idxtmp != 0);
idxtmp = 0 - idxtmp;
}
#endif
switch(opc){
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
case Instruction::UDiv:
case Instruction::SDiv:
case Instruction::URem:
case Instruction::SRem:{
// TODO: add for i1, i8. Support i32 and i64 first
if(! (BI->getType()->isIntegerTy(32) || BI->getType()->isIntegerTy(64))){
continue;
}
genLVR(BI, F.getName(), idxtmp);
genUOI(BI, F.getName(), idxtmp);
genROV(BI, F.getName(), idxtmp);
genABV(BI, F.getName(), idxtmp);
genAOR(BI, F.getName(), idxtmp);
break;
}
case Instruction::ICmp:{
if(! (BI->getOperand(0)->getType()->isIntegerTy(32) ||
BI->getOperand(0)->getType()->isIntegerTy(64)) ){
continue;
}
genLVR(BI, F.getName(), idxtmp);
genUOI(BI, F.getName(), idxtmp);
genROV(BI, F.getName(), idxtmp);
genABV(BI, F.getName(), idxtmp);
genROR(BI, F.getName(), idxtmp);
break;
}
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:{
// TODO: add for i1, i8. Support i32 and i64 first
if(! (BI->getType()->isIntegerTy(32) || BI->getType()->isIntegerTy(64))){
continue;
}
genLVR(BI, F.getName(), idxtmp);
genUOI(BI, F.getName(), idxtmp);
genROV(BI, F.getName(), idxtmp);
genABV(BI, F.getName(), idxtmp);
genLOR(BI, F.getName(), idxtmp);
break;
}
case Instruction::Call:
{
CallInst* call = cast<CallInst>(BI);
// TODO: omit function-pointer
if(call->getCalledFunction() == NULL){
continue;
}
/*Value* callee = dyn_cast<Value>(&*(call->op_end() - 1));
if(callee->getType()->isPointerTy()){
continue;
}*/
StringRef name = call->getCalledFunction()->getName();
if(name.startswith("llvm")){//omit llvm inside functions
continue;
}
// TODO: add for ommiting i8. Support i32 and i64 first
if(! ( isSupportedType(BI->getType())|| BI->getType()->isVoidTy() ) ){
continue;
}
//.........这里部分代码省略.........
示例9: edit_template_function
void HeterotbbTransform::edit_template_function (Module &M,Function* F,Function* new_join,GlobalVariable *old_gb,Value *gb) {
SmallVector<Value*, 16> Args; // Argument lists to the new call
vector<Instruction *> toDelete;
// old_gb->dump();
// gb->dump();
Constant *Ids[2];
for (Function::iterator BI=F->begin(),BE = F->end(); BI != BE; ++BI) {
for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE; ++II) {
GetElementPtrInst *GEP;
GlobalVariable *op;
if (isa<CallInst>(II) || isa<InvokeInst>(II)) {
CallSite CI(cast<Instruction>(II));
//replace dummy reduce with new reduce
if(CI.getCalledFunction()->getName().equals("__join_reduce_hetero")) {
Args.clear();
CastInst *newarg1 = CastInst::Create(Instruction::BitCast, CI.getArgument(0), new_join->arg_begin()->getType(), "arg1",CI.getInstruction());
Args.push_back(newarg1);
CastInst *newarg2 = CastInst::Create(Instruction::BitCast, CI.getArgument(1), new_join->arg_begin()->getType(), "arg2", CI.getInstruction());
Args.push_back(newarg2);
//no need to set attributes
Instruction *NewCall = CallInst::Create(new_join, Args, "", CI.getInstruction());
cast<CallInst>(NewCall)->setCallingConv(CI.getCallingConv());
toDelete.push_back(CI.getInstruction());
DEBUG(dbgs()<<"Joins Replaced\n");
}
}
/*
%arrayidx18 = getelementptr inbounds i32 addrspace(3)* getelementptr
inbounds ([192 x i32] addrspace(3)* @opencl_kernel_join_name_local_arr, i32 0, i32 0),
i64 %idxprom1
*/
if((GEP = dyn_cast<GetElementPtrInst>(II)) /*&&
(op = dyn_cast<GlobalVariable>(GEP->getOperand(0)))*/ /*&&
(op->getName().equals("opencl_kernel_join_name_local_arr"))*/) {
//II->dump();
Value *val= II->getOperand(0);
if(Constant *op=dyn_cast<ConstantExpr>(val)) {
//II->dump();
//II->getOperand(1)->dump();
/*Ids[0]=cast<Constant>(op->getOperand(1));
Ids[1]=cast<Constant>(op->getOperand(1));
Constant *new_op = ConstantExpr::getInBoundsGetElementPtr(cast<Constant>(gb),Ids,2);
new_op->dump();
Instruction *inst = GetElementPtrInst::CreateInBounds(new_op, II->getOperand(1), II->getName()+"_temp",II);
Value *Elts[] = {MDString::get(M.getContext(), "local_access")};
MDNode *Node = MDNode::get(M.getContext(), Elts);
inst->setMetadata("local_access",Node);
inst->dump();
II->replaceAllUsesWith(inst);
toDelete.push_back(II);
*/
Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(M.getContext()), 0),
ConstantInt::get(Type::getInt32Ty(M.getContext()), 0)
};
//gb->getType()->dump();
//gb->dump();
Instruction *inst_= GetElementPtrInst::CreateInBounds(gb, Idxs, /*Idxs+2,*/ II->getName()+"_temp_",II);
//inst_->dump();
Instruction *inst= GetElementPtrInst::CreateInBounds(inst_, II->getOperand(1), II->getName()+"_temp",II);
Value *Elts[] = {MDString::get(M.getContext(), inst->getName())};
MDNode *Node = MDNode::get(M.getContext(), Elts);
inst->setMetadata("local_access",Node);
//inst->dump();
II->replaceAllUsesWith(inst);
toDelete.push_back(II);
}
}
}
}
while(!toDelete.empty()) {
Instruction *g = toDelete.back();
toDelete.pop_back();
g->eraseFromParent();
}
}
示例10: runOnModule
bool GenericToNVVM::runOnModule(Module &M) {
// Create a clone of each global variable that has the default address space.
// The clone is created with the global address space specifier, and the pair
// of original global variable and its clone is placed in the GVMap for later
// use.
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E;) {
GlobalVariable *GV = &*I++;
if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
!llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
!llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
GlobalVariable *NewGV = new GlobalVariable(
M, GV->getValueType(), GV->isConstant(),
GV->getLinkage(),
GV->hasInitializer() ? GV->getInitializer() : nullptr,
"", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
NewGV->copyAttributesFrom(GV);
GVMap[GV] = NewGV;
}
}
// Return immediately, if every global variable has a specific address space
// specifier.
if (GVMap.empty()) {
return false;
}
// Walk through the instructions in function defitinions, and replace any use
// of original global variables in GVMap with a use of the corresponding
// copies in GVMap. If necessary, promote constants to instructions.
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
if (I->isDeclaration()) {
continue;
}
IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
++BBI) {
for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
++II) {
for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
Value *Operand = II->getOperand(i);
if (isa<Constant>(Operand)) {
II->setOperand(
i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
}
}
}
}
ConstantToValueMap.clear();
}
// Copy GVMap over to a standard value map.
ValueToValueMapTy VM;
for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
VM[I->first] = I->second;
// Walk through the metadata section and update the debug information
// associated with the global variables in the default address space.
for (NamedMDNode &I : M.named_metadata()) {
remapNamedMDNode(VM, &I);
}
// Walk through the global variable initializers, and replace any use of
// original global variables in GVMap with a use of the corresponding copies
// in GVMap. The copies need to be bitcast to the original global variable
// types, as we cannot use cvta in global variable initializers.
for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
GlobalVariable *GV = I->first;
GlobalVariable *NewGV = I->second;
// Remove GV from the map so that it can be RAUWed. Note that
// DenseMap::erase() won't invalidate any iterators but this one.
auto Next = std::next(I);
GVMap.erase(I);
I = Next;
Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
// At this point, the remaining uses of GV should be found only in global
// variable initializers, as other uses have been already been removed
// while walking through the instructions in function definitions.
GV->replaceAllUsesWith(BitCastNewGV);
std::string Name = GV->getName();
GV->eraseFromParent();
NewGV->setName(Name);
}
assert(GVMap.empty() && "Expected it to be empty by now");
return true;
}
示例11: getOperandName
string getOperandName(BasicBlock::iterator inst)
{
return (inst->getOperand(1))->getName().str();
}
示例12: shouldSpeculateInstrs
/// Determine whether the instructions in this range may be safely and cheaply
/// speculated. This is not an important enough situation to develop complex
/// heuristics. We handle a single arithmetic instruction along with any type
/// conversions.
static bool shouldSpeculateInstrs(BasicBlock::iterator Begin,
BasicBlock::iterator End, Loop *L) {
bool seenIncrement = false;
bool MultiExitLoop = false;
if (!L->getExitingBlock())
MultiExitLoop = true;
for (BasicBlock::iterator I = Begin; I != End; ++I) {
if (!isSafeToSpeculativelyExecute(I))
return false;
if (isa<DbgInfoIntrinsic>(I))
continue;
switch (I->getOpcode()) {
default:
return false;
case Instruction::GetElementPtr:
// GEPs are cheap if all indices are constant.
if (!cast<GEPOperator>(I)->hasAllConstantIndices())
return false;
// fall-thru to increment case
case Instruction::Add:
case Instruction::Sub:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr: {
Value *IVOpnd = !isa<Constant>(I->getOperand(0))
? I->getOperand(0)
: !isa<Constant>(I->getOperand(1))
? I->getOperand(1)
: nullptr;
if (!IVOpnd)
return false;
// If increment operand is used outside of the loop, this speculation
// could cause extra live range interference.
if (MultiExitLoop) {
for (User *UseI : IVOpnd->users()) {
auto *UserInst = cast<Instruction>(UseI);
if (!L->contains(UserInst))
return false;
}
}
if (seenIncrement)
return false;
seenIncrement = true;
break;
}
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
// ignore type conversions
break;
}
}
return true;
}
示例13: fixSideEntrances
void SuperBlock::fixSideEntrances() {
// due to merging of BBs, some superblocks may have 1 BB remaining
list<map<BasicBlock*, list<BasicBlock*> >::iterator > delSuperBlocks;
for (map<BasicBlock*, list<BasicBlock*> >::iterator sp = superBlocks.begin(),
sp_e = superBlocks.end(); sp != sp_e; ++sp) {
// we need to keep track of the predecessor of the current basic block
// being checked
BasicBlock* prev = sp->first;
// don't clone basic blocks if the code size threshold is achieved
if (currCodeSize/originalCodeSize > CODE_EXPANSION_THRESHOLD) {
break;
}
// the first basic block for a superblock need not be duplicated
for (list<BasicBlock*>::iterator bb = sp->second.begin(),
bb_e = sp->second.end(); bb != bb_e; ++bb) {
// first, collect all predecessors for this BB
// (note: we could not just iterate through as the predecessor set may
// change
list<BasicBlock*> predBBs;
for (pred_iterator pred = pred_begin(*bb), pred_e = pred_end(*bb);
pred != pred_e; ++pred) {
predBBs.push_back(*pred);
}
// now, walk through all predecessors of this current basic block
BasicBlock* clonedBB = NULL;
for (list<BasicBlock*>::iterator pred = predBBs.begin(),
pred_e = predBBs.end(); pred != pred_e; ++pred) {
// if it is not the predecessor of this current basic block present in
// the superblock, duplicate!
if (*pred != prev) {
// there is no need to clone this BB multiple times
if (clonedBB == NULL) {
ValueToValueMapTy vmap;
// clone this basic block, and place the corresponding code after
// the last BB of this superblock
clonedBB = CloneBasicBlock(*bb, vmap, ".cloned",
(*bb)->getParent());
vmap[*bb] = clonedBB;
/*
errs() << "@@ BEFORE: " << *clonedBB << "\n";
// fix phi nodes in the cloned BB
for (BasicBlock::iterator I = clonedBB->begin(); isa<PHINode>(I); ++I) {
PHINode* PN = dyn_cast<PHINode>(I);
int bbIdx = PN->getBasicBlockIndex(prev);
if (bbIdx != -1) {
PN->removeIncomingValue(bbIdx, false);
}
}
*/
// add size of duplicated BBs to total code size count
currCodeSize += clonedBB->size();
// modify operands in this basic block
for (BasicBlock::iterator instr = clonedBB->begin(),
instr_e = clonedBB->end(); instr != instr_e; ++instr) {
for (unsigned idx = 0, num_ops = instr->getNumOperands();
idx < num_ops; ++idx) {
Value* op = instr->getOperand(idx);
ValueToValueMapTy::iterator op_it = vmap.find(op);
if (op_it != vmap.end()) {
instr->setOperand(idx, op_it->second);
}
}
}
}
// remove phi nodes into this BB in the trace
/*
for (BasicBlock::iterator I = (*bb)->begin(); isa<PHINode>(I); ++I) {
PHINode* PN = dyn_cast<PHINode>(I);
int bbIdx = PN->getBasicBlockIndex(*pred);
if (bbIdx != -1) {
PN->removeIncomingValue(bbIdx, false);
}
}
*/
// modify the branch instruction of the predecessor not in the superblock to
// branch to the cloned basic block
Instruction* br_instr = (*pred)->getTerminator();
br_instr->replaceUsesOfWith((Value*)*bb, (Value*)clonedBB);
}
}
// determine if we can merge the BB (definitely can be merged), and its clone
// with theirpredecessors
if (clonedBB != NULL) {
if (MergeBlockIntoPredecessor(*bb, this)) {
// since we have merged this BB, delete from our superblock mappings
partOfSuperBlock.erase(*bb);
bb = sp->second.erase(bb);
--bb;
//.........这里部分代码省略.........
示例14: mangler
/// InputFilename is a LLVM bitcode file. Read it using bitcode reader.
/// Collect global functions and symbol names in symbols vector.
/// Collect external references in references vector.
/// Return LTO_READ_SUCCESS if there is no error.
enum LTOStatus
LTO::readLLVMObjectFile(const std::string &InputFilename,
NameToSymbolMap &symbols,
std::set<std::string> &references)
{
Module *m = getModule(InputFilename);
if (!m)
return LTO_READ_FAILURE;
// Collect Target info
getTarget(m);
if (!Target)
return LTO_READ_FAILURE;
// Use mangler to add GlobalPrefix to names to match linker names.
// FIXME : Instead of hard coding "-" use GlobalPrefix.
Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix());
modules.push_back(m);
for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) {
LTOLinkageTypes lt = getLTOLinkageType(f);
LTOVisibilityTypes vis = getLTOVisibilityType(f);
if (!f->isDeclaration() && lt != LTOInternalLinkage
&& strncmp (f->getName().c_str(), "llvm.", 5)) {
int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment());
LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, f, f->getName(),
mangler.getValueName(f),
Log2_32(alignment));
symbols[newSymbol->getMangledName()] = newSymbol;
allSymbols[newSymbol->getMangledName()] = newSymbol;
}
// Collect external symbols referenced by this function.
for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b)
for (BasicBlock::iterator i = b->begin(), be = b->end();
i != be; ++i) {
for (unsigned count = 0, total = i->getNumOperands();
count != total; ++count)
findExternalRefs(i->getOperand(count), references, mangler);
}
}
for (Module::global_iterator v = m->global_begin(), e = m->global_end();
v != e; ++v) {
LTOLinkageTypes lt = getLTOLinkageType(v);
LTOVisibilityTypes vis = getLTOVisibilityType(v);
if (!v->isDeclaration() && lt != LTOInternalLinkage
&& strncmp (v->getName().c_str(), "llvm.", 5)) {
const TargetData *TD = Target->getTargetData();
LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, v, v->getName(),
mangler.getValueName(v),
TD->getPreferredAlignmentLog(v));
symbols[newSymbol->getMangledName()] = newSymbol;
allSymbols[newSymbol->getMangledName()] = newSymbol;
for (unsigned count = 0, total = v->getNumOperands();
count != total; ++count)
findExternalRefs(v->getOperand(count), references, mangler);
}
}
return LTO_READ_SUCCESS;
}
示例15: processBasicBlock
bool ReplaceNopCastsAndByteSwaps::processBasicBlock(BasicBlock& BB)
{
bool Changed = false;
/**
* First pass: replace nopCasts with bitcasts and bswap intrinsics with logic operations
*/
for ( BasicBlock::iterator it = BB.begin(); it != BB.end(); )
{
Instruction * Inst = it++;
if (isNopCast(Inst) )
{
assert( isa<CallInst>(Inst) );
CallInst * call = cast<CallInst>(Inst);
if ( TypeSupport::isClientType( call->getType()) )
{
llvm::errs() << "Cast of client type: " << *call << "\n";
continue;
}
if ( TypeSupport::isClientType( call->getArgOperand(0)->getType()) )
{
llvm::errs() << "Cast of client type: " << *call->getArgOperand(0) << "\n";
continue;
}
ReplaceInstWithInst( call, BitCastInst::Create( Instruction::CastOps::BitCast, call->getArgOperand(0), call->getType() ) );
Changed = true;
}
else if( IntrinsicInst* II = dyn_cast<IntrinsicInst>(Inst) )
{
if(II->getIntrinsicID() == Intrinsic::bswap)
{
IL->LowerIntrinsicCall(II);
Changed = true;
}
else if(II->getIntrinsicID() == Intrinsic::cheerp_deallocate)
{
II->eraseFromParent();
Changed = true;
}
}
}
/**
* Second pass: collapse bitcasts of bitcasts.
*
* Note: this might leave some dead instruction around, but we don't care since bitcasts are inlined anyway
*/
for ( BasicBlock::iterator it = BB.begin(); it != BB.end(); ++it )
{
if ( isa<BitCastInst>(it) )
{
while ( BitCastInst * src = dyn_cast<BitCastInst>(it->getOperand(0) ) )
{
it->setOperand(0, src->getOperand(0) );
Changed = true;
}
}
}
return Changed;
}