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; }
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; }
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); } }
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); } } } }
/// eliminateUnconditionalBranch - Clone the instructions from the destination /// block into the source block, eliminating the specified unconditional branch. /// If the destination block defines values used by successors of the dest /// block, we may need to insert PHI nodes. /// void TailDup::eliminateUnconditionalBranch(BranchInst *Branch) { BasicBlock *SourceBlock = Branch->getParent(); BasicBlock *DestBlock = Branch->getSuccessor(0); assert(SourceBlock != DestBlock && "Our predicate is broken!"); DEBUG(errs() << "TailDuplication[" << SourceBlock->getParent()->getName() << "]: Eliminating branch: " << *Branch); // See if we can avoid duplicating code by moving it up to a dominator of both // blocks. if (BasicBlock *DomBlock = FindObviousSharedDomOf(SourceBlock, DestBlock)) { DEBUG(errs() << "Found shared dominator: " << DomBlock->getName() << "\n"); // If there are non-phi instructions in DestBlock that have no operands // defined in DestBlock, and if the instruction has no side effects, we can // move the instruction to DomBlock instead of duplicating it. BasicBlock::iterator BBI = DestBlock->getFirstNonPHI(); while (!isa<TerminatorInst>(BBI)) { Instruction *I = BBI++; bool CanHoist = I->isSafeToSpeculativelyExecute() && !I->mayReadFromMemory(); if (CanHoist) { for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(op))) if (OpI->getParent() == DestBlock || (isa<InvokeInst>(OpI) && OpI->getParent() == DomBlock)) { CanHoist = false; break; } if (CanHoist) { // Remove from DestBlock, move right before the term in DomBlock. DestBlock->getInstList().remove(I); DomBlock->getInstList().insert(DomBlock->getTerminator(), I); DEBUG(errs() << "Hoisted: " << *I); } } } } // Tail duplication can not update SSA properties correctly if the values // defined in the duplicated tail are used outside of the tail itself. For // this reason, we spill all values that are used outside of the tail to the // stack. for (BasicBlock::iterator I = DestBlock->begin(); I != DestBlock->end(); ++I) if (I->isUsedOutsideOfBlock(DestBlock)) { // We found a use outside of the tail. Create a new stack slot to // break this inter-block usage pattern. DemoteRegToStack(*I); } // We are going to have to map operands from the original block B to the new // copy of the block B'. If there are PHI nodes in the DestBlock, these PHI // nodes also define part of this mapping. Loop over these PHI nodes, adding // them to our mapping. // std::map<Value*, Value*> ValueMapping; BasicBlock::iterator BI = DestBlock->begin(); bool HadPHINodes = isa<PHINode>(BI); for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI) ValueMapping[PN] = PN->getIncomingValueForBlock(SourceBlock); // Clone the non-phi instructions of the dest block into the source block, // keeping track of the mapping... // for (; BI != DestBlock->end(); ++BI) { Instruction *New = BI->clone(); New->setName(BI->getName()); SourceBlock->getInstList().push_back(New); ValueMapping[BI] = New; } // Now that we have built the mapping information and cloned all of the // instructions (giving us a new terminator, among other things), walk the new // instructions, rewriting references of old instructions to use new // instructions. // BI = Branch; ++BI; // Get an iterator to the first new instruction for (; BI != SourceBlock->end(); ++BI) for (unsigned i = 0, e = BI->getNumOperands(); i != e; ++i) { std::map<Value*, Value*>::const_iterator I = ValueMapping.find(BI->getOperand(i)); if (I != ValueMapping.end()) BI->setOperand(i, I->second); } // Next we check to see if any of the successors of DestBlock had PHI nodes. // If so, we need to add entries to the PHI nodes for SourceBlock now. for (succ_iterator SI = succ_begin(DestBlock), SE = succ_end(DestBlock); SI != SE; ++SI) { BasicBlock *Succ = *SI; for (BasicBlock::iterator PNI = Succ->begin(); isa<PHINode>(PNI); ++PNI) { PHINode *PN = cast<PHINode>(PNI); // Ok, we have a PHI node. Figure out what the incoming value was for the // DestBlock. Value *IV = PN->getIncomingValueForBlock(DestBlock); // Remap the value if necessary... std::map<Value*, Value*>::const_iterator I = ValueMapping.find(IV); if (I != ValueMapping.end()) IV = I->second; PN->addIncoming(IV, SourceBlock); } } // Next, remove the old branch instruction, and any PHI node entries that we // had. BI = Branch; ++BI; // Get an iterator to the first new instruction DestBlock->removePredecessor(SourceBlock); // Remove entries in PHI nodes... SourceBlock->getInstList().erase(Branch); // Destroy the uncond branch... // Final step: now that we have finished everything up, walk the cloned // instructions one last time, constant propagating and DCE'ing them, because // they may not be needed anymore. // if (HadPHINodes) { while (BI != SourceBlock->end()) { Instruction *Inst = BI++; if (isInstructionTriviallyDead(Inst)) Inst->eraseFromParent(); else if (Constant *C = ConstantFoldInstruction(Inst)) { Inst->replaceAllUsesWith(C); Inst->eraseFromParent(); } } } ++NumEliminated; // We just killed a branch! }
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; }
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; if (sp->second.empty()) { delSuperBlocks.push_back(sp); } } MergeBlockIntoPredecessor(clonedBB, this); } prev = *bb; } } // erase some superblocks (which only have 1 BB remaining) for (list<map<BasicBlock*, list<BasicBlock*> >::iterator >::iterator del = delSuperBlocks.begin(), del_e = delSuperBlocks.end(); del != del_e; ++del) { superBlocks.erase(*del); } }
/// 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; }