/// Calculate the additional register pressure that the registers used in MI /// cause. /// /// If 'ConsiderSeen' is true, updates 'RegSeen' and uses the information to /// figure out which usages are live-ins. /// FIXME: Figure out a way to consider 'RegSeen' from all code paths. DenseMap<unsigned, int> MachineLICM::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen, bool ConsiderUnseenAsDef) { DenseMap<unsigned, int> Cost; if (MI->isImplicitDef()) return Cost; for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || MO.isImplicit()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; // FIXME: It seems bad to use RegSeen only for some of these calculations. bool isNew = ConsiderSeen ? RegSeen.insert(Reg).second : false; const TargetRegisterClass *RC = MRI->getRegClass(Reg); RegClassWeight W = TRI->getRegClassWeight(RC); int RCCost = 0; if (MO.isDef()) RCCost = W.RegWeight; else { bool isKill = isOperandKill(MO, MRI); if (isNew && !isKill && ConsiderUnseenAsDef) // Haven't seen this, it must be a livein. RCCost = W.RegWeight; else if (!isNew && isKill) RCCost = -W.RegWeight; } if (RCCost == 0) continue; const int *PS = TRI->getRegClassPressureSets(RC); for (; *PS != -1; ++PS) { if (Cost.find(*PS) == Cost.end()) Cost[*PS] = RCCost; else Cost[*PS] += RCCost; } } return Cost; }
void MachineCopyPropagation::SourceNoLongerAvailable(unsigned Reg, SourceMap &SrcMap, DenseMap<unsigned, MachineInstr*> &AvailCopyMap) { for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { SourceMap::iterator SI = SrcMap.find(*AI); if (SI != SrcMap.end()) { const DestList& Defs = SI->second; for (DestList::const_iterator I = Defs.begin(), E = Defs.end(); I != E; ++I) { unsigned MappedDef = *I; // Source of copy is no longer available for propagation. if (AvailCopyMap.erase(MappedDef)) { for (MCSubRegIterator SR(MappedDef, TRI); SR.isValid(); ++SR) AvailCopyMap.erase(*SR); } } } } }
/// getVR - Return the virtual register corresponding to the specified result /// of the specified node. unsigned ScheduleDAGSDNodes::getVR(SDValue Op, DenseMap<SDValue, unsigned> &VRBaseMap) { if (Op.isMachineOpcode() && Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { // Add an IMPLICIT_DEF instruction before every use. unsigned VReg = getDstOfOnlyCopyToRegUse(Op.getNode(), Op.getResNo()); // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc // does not include operand register class info. if (!VReg) { const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType()); VReg = MRI.createVirtualRegister(RC); } BuildMI(BB, Op.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF),VReg); return VReg; } DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op); assert(I != VRBaseMap.end() && "Node emitted out of order - late"); return I->second; }
// bypassSlowDivision - This optimization identifies DIV instructions that can // be profitably bypassed and carried out with a shorter, faster divide. bool llvm::bypassSlowDivision(Function &F, Function::iterator &I, const DenseMap<unsigned int, unsigned int> &BypassWidths) { DivCacheTy DivCache; bool MadeChange = false; for (BasicBlock::iterator J = I->begin(); J != I->end(); J++) { // Get instruction details unsigned Opcode = J->getOpcode(); bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv; bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem; bool UseSignedOp = Opcode == Instruction::SDiv || Opcode == Instruction::SRem; // Only optimize div or rem ops if (!UseDivOp && !UseRemOp) continue; // Skip division on vector types, only optimize integer instructions if (!J->getType()->isIntegerTy()) continue; // Get bitwidth of div/rem instruction IntegerType *T = cast<IntegerType>(J->getType()); unsigned int bitwidth = T->getBitWidth(); // Continue if bitwidth is not bypassed DenseMap<unsigned int, unsigned int>::const_iterator BI = BypassWidths.find(bitwidth); if (BI == BypassWidths.end()) continue; // Get type for div/rem instruction with bypass bitwidth IntegerType *BT = IntegerType::get(J->getContext(), BI->second); MadeChange |= reuseOrInsertFastDiv(F, I, J, BT, UseDivOp, UseSignedOp, DivCache); } return MadeChange; }
/// foldImmediate - Try folding register operands that are defined by move /// immediate instructions, i.e. a trivial constant folding optimization, if /// and only if the def and use are in the same BB. bool PeepholeOptimizer::foldImmediate(MachineInstr *MI, MachineBasicBlock *MBB, SmallSet<unsigned, 4> &ImmDefRegs, DenseMap<unsigned, MachineInstr*> &ImmDefMIs) { for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || MO.isDef()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; if (ImmDefRegs.count(Reg) == 0) continue; DenseMap<unsigned, MachineInstr*>::iterator II = ImmDefMIs.find(Reg); assert(II != ImmDefMIs.end()); if (TII->FoldImmediate(MI, II->second, Reg, MRI)) { ++NumImmFold; return true; } } return false; }
bool PropagateJuliaAddrspaces::runOnFunction(Function &F) { visit(F); for (auto it : ToInsert) it.first->insertBefore(it.second); for (Instruction *I : ToDelete) I->eraseFromParent(); ToInsert.clear(); ToDelete.clear(); LiftingMap.clear(); Visited.clear(); return true; }
/// getNonLocalDependency - Fills the passed-in map with the non-local /// dependencies of the queries. The map will contain NonLocal for /// blocks between the query and its dependencies. void MemoryDependenceAnalysis::getNonLocalDependency(Instruction* query, DenseMap<BasicBlock*, Value*>& resp) { if (depGraphNonLocal.count(query)) { DenseMap<BasicBlock*, Value*>& cached = depGraphNonLocal[query]; NumCacheNonlocal++; SmallVector<BasicBlock*, 4> dirtied; for (DenseMap<BasicBlock*, Value*>::iterator I = cached.begin(), E = cached.end(); I != E; ++I) if (I->second == Dirty) dirtied.push_back(I->first); for (SmallVector<BasicBlock*, 4>::iterator I = dirtied.begin(), E = dirtied.end(); I != E; ++I) { Instruction* localDep = getDependency(query, 0, *I); if (localDep != NonLocal) cached[*I] = localDep; else { cached.erase(*I); nonLocalHelper(query, *I, cached); } } resp = cached; return; } else NumUncacheNonlocal++; // If not, go ahead and search for non-local deps. nonLocalHelper(query, query->getParent(), resp); // Update the non-local dependency cache for (DenseMap<BasicBlock*, Value*>::iterator I = resp.begin(), E = resp.end(); I != E; ++I) { depGraphNonLocal[query].insert(*I); reverseDepNonLocal[I->second].insert(query); } }
void ScheduleDAG::EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap) { for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { if (I->isCtrl()) continue; // ignore chain preds if (I->getSUnit()->CopyDstRC) { // Copy to physical register. DenseMap<SUnit*, unsigned>::iterator VRI = VRBaseMap.find(I->getSUnit()); assert(VRI != VRBaseMap.end() && "Node emitted out of order - late"); // Find the destination physical register. unsigned Reg = 0; for (SUnit::const_succ_iterator II = SU->Succs.begin(), EE = SU->Succs.end(); II != EE; ++II) { if (II->getReg()) { Reg = II->getReg(); break; } } bool Success = TII->copyRegToReg(*BB, InsertPos, Reg, VRI->second, SU->CopyDstRC, SU->CopySrcRC, DebugLoc()); (void)Success; assert(Success && "copyRegToReg failed!"); } else { // Copy from physical register. assert(I->getReg() && "Unknown physical register!"); unsigned VRBase = MRI.createVirtualRegister(SU->CopyDstRC); bool isNew = VRBaseMap.insert(std::make_pair(SU, VRBase)).second; isNew = isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); bool Success = TII->copyRegToReg(*BB, InsertPos, VRBase, I->getReg(), SU->CopyDstRC, SU->CopySrcRC, DebugLoc()); (void)Success; assert(Success && "copyRegToReg failed!"); } break; } }
bool RecurrenceDescriptor::isFirstOrderRecurrence( PHINode *Phi, Loop *TheLoop, DenseMap<Instruction *, Instruction *> &SinkAfter, DominatorTree *DT) { // Ensure the phi node is in the loop header and has two incoming values. if (Phi->getParent() != TheLoop->getHeader() || Phi->getNumIncomingValues() != 2) return false; // Ensure the loop has a preheader and a single latch block. The loop // vectorizer will need the latch to set up the next iteration of the loop. auto *Preheader = TheLoop->getLoopPreheader(); auto *Latch = TheLoop->getLoopLatch(); if (!Preheader || !Latch) return false; // Ensure the phi node's incoming blocks are the loop preheader and latch. if (Phi->getBasicBlockIndex(Preheader) < 0 || Phi->getBasicBlockIndex(Latch) < 0) return false; // Get the previous value. The previous value comes from the latch edge while // the initial value comes form the preheader edge. auto *Previous = dyn_cast<Instruction>(Phi->getIncomingValueForBlock(Latch)); if (!Previous || !TheLoop->contains(Previous) || isa<PHINode>(Previous) || SinkAfter.count(Previous)) // Cannot rely on dominance due to motion. return false; // Ensure every user of the phi node is dominated by the previous value. // The dominance requirement ensures the loop vectorizer will not need to // vectorize the initial value prior to the first iteration of the loop. // TODO: Consider extending this sinking to handle other kinds of instructions // and expressions, beyond sinking a single cast past Previous. if (Phi->hasOneUse()) { auto *I = Phi->user_back(); if (I->isCast() && (I->getParent() == Phi->getParent()) && I->hasOneUse() && DT->dominates(Previous, I->user_back())) { if (!DT->dominates(Previous, I)) // Otherwise we're good w/o sinking. SinkAfter[I] = Previous; return true; } } for (User *U : Phi->users()) if (auto *I = dyn_cast<Instruction>(U)) { if (!DT->dominates(Previous, I)) return false; } return true; }
// Calculate the intersection of all the FinalStates for a BasicBlock's // predecessors. static int getPredState(DenseMap<BasicBlock *, int> &FinalStates, Function &F, int ParentBaseState, BasicBlock *BB) { // The entry block has no predecessors but we know that the prologue always // sets us up with a fixed state. if (&F.getEntryBlock() == BB) return ParentBaseState; // This is an EH Pad, conservatively report this basic block as overdefined. if (BB->isEHPad()) return OverdefinedState; int CommonState = OverdefinedState; for (BasicBlock *PredBB : predecessors(BB)) { // We didn't manage to get a state for one of these predecessors, // conservatively report this basic block as overdefined. auto PredEndState = FinalStates.find(PredBB); if (PredEndState == FinalStates.end()) return OverdefinedState; // This code is reachable via exceptional control flow, // conservatively report this basic block as overdefined. if (isa<CatchReturnInst>(PredBB->getTerminator())) return OverdefinedState; int PredState = PredEndState->second; assert(PredState != OverdefinedState && "overdefined BBs shouldn't be in FinalStates"); if (CommonState == OverdefinedState) CommonState = PredState; // At least two predecessors have different FinalStates, // conservatively report this basic block as overdefined. if (CommonState != PredState) return OverdefinedState; } return CommonState; }
std::vector<FileCoverageSummary> CoverageReport::prepareFileReports(const coverage::CoverageMapping &Coverage, FileCoverageSummary &Totals, ArrayRef<StringRef> Files) { std::vector<FileCoverageSummary> FileReports; unsigned LCP = 0; if (Files.size() > 1) LCP = getLongestCommonPrefixLen(Files); for (StringRef Filename : Files) { FileCoverageSummary Summary(Filename.drop_front(LCP)); // Map source locations to aggregate function coverage summaries. DenseMap<std::pair<unsigned, unsigned>, FunctionCoverageSummary> Summaries; for (const auto &F : Coverage.getCoveredFunctions(Filename)) { FunctionCoverageSummary Function = FunctionCoverageSummary::get(F); auto StartLoc = F.CountedRegions[0].startLoc(); auto UniquedSummary = Summaries.insert({StartLoc, Function}); if (!UniquedSummary.second) UniquedSummary.first->second.update(Function); Summary.addInstantiation(Function); Totals.addInstantiation(Function); } for (const auto &UniquedSummary : Summaries) { const FunctionCoverageSummary &FCS = UniquedSummary.second; Summary.addFunction(FCS); Totals.addFunction(FCS); } FileReports.push_back(Summary); } return FileReports; }
/// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee /// into the caller, update the specified callgraph to reflect the changes we /// made. Note that it's possible that not all code was copied over, so only /// some edges of the callgraph may remain. static void UpdateCallGraphAfterInlining(CallSite CS, Function::iterator FirstNewBlock, DenseMap<const Value*, Value*> &ValueMap, CallGraph &CG) { const Function *Caller = CS.getInstruction()->getParent()->getParent(); const Function *Callee = CS.getCalledFunction(); CallGraphNode *CalleeNode = CG[Callee]; CallGraphNode *CallerNode = CG[Caller]; // Since we inlined some uninlined call sites in the callee into the caller, // add edges from the caller to all of the callees of the callee. CallGraphNode::iterator I = CalleeNode->begin(), E = CalleeNode->end(); // Consider the case where CalleeNode == CallerNode. CallGraphNode::CalledFunctionsVector CallCache; if (CalleeNode == CallerNode) { CallCache.assign(I, E); I = CallCache.begin(); E = CallCache.end(); } for (; I != E; ++I) { const Instruction *OrigCall = I->first.getInstruction(); DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall); // Only copy the edge if the call was inlined! if (VMI != ValueMap.end() && VMI->second) { // If the call was inlined, but then constant folded, there is no edge to // add. Check for this case. if (Instruction *NewCall = dyn_cast<Instruction>(VMI->second)) CallerNode->addCalledFunction(CallSite::get(NewCall), I->second); } } // Update the call graph by deleting the edge from Callee to Caller. We must // do this after the loop above in case Caller and Callee are the same. CallerNode->removeCallEdgeFor(CS); }
bool FixFunctionBitcasts::runOnModule(Module &M) { SmallVector<std::pair<Use *, Function *>, 0> Uses; // Collect all the places that need wrappers. for (Function &F : M) FindUses(&F, F, Uses); DenseMap<std::pair<Function *, FunctionType *>, Function *> Wrappers; for (auto &UseFunc : Uses) { Use *U = UseFunc.first; Function *F = UseFunc.second; PointerType *PTy = cast<PointerType>(U->get()->getType()); FunctionType *Ty = dyn_cast<FunctionType>(PTy->getElementType()); // If the function is casted to something like i8* as a "generic pointer" // to be later casted to something else, we can't generate a wrapper for it. // Just ignore such casts for now. if (!Ty) continue; auto Pair = Wrappers.insert(std::make_pair(std::make_pair(F, Ty), nullptr)); if (Pair.second) Pair.first->second = CreateWrapper(F, Ty); Function *Wrapper = Pair.first->second; if (!Wrapper) continue; if (isa<Constant>(U->get())) U->get()->replaceAllUsesWith(Wrapper); else U->set(Wrapper); } return true; }
/// Collect all the loop live out values in the map that maps original live out /// value to live out value in the cloned loop. static void collectLoopLiveOutValues( DenseMap<SILValue, SmallVector<SILValue, 8>> &LoopLiveOutValues, SILLoop *Loop, DenseMap<SILValue, SILValue> &ClonedValues, DenseMap<SILInstruction *, SILInstruction *> &ClonedInstructions) { for (auto *Block : Loop->getBlocks()) { // Look at block arguments. for (auto *Arg : Block->getBBArgs()) { for (auto *Op : Arg->getUses()) { // Is this use outside the loop? if (!Loop->contains(Op->getUser())) { auto ArgumentValue = SILValue(Arg); assert(ClonedValues.count(ArgumentValue) && "Unmapped Argument!"); if (!LoopLiveOutValues.count(ArgumentValue)) LoopLiveOutValues[ArgumentValue].push_back( ClonedValues[ArgumentValue]); } } } // And the instructions. for (auto &Inst : *Block) { for (auto *Op : Inst.getUses()) { // Is this use outside the loop. if (!Loop->contains(Op->getUser())) { auto UsedValue = Op->get(); assert(UsedValue.getDef() == &Inst && "Instructions must match"); assert(ClonedInstructions.count(&Inst) && "Unmapped instruction!"); if (!LoopLiveOutValues.count(UsedValue)) LoopLiveOutValues[UsedValue].push_back(SILValue( ClonedInstructions[&Inst], UsedValue.getResultNumber())); } } } } }
void HexagonDCE::removeOperand(NodeAddr<InstrNode*> IA, unsigned OpNum) { MachineInstr *MI = NodeAddr<StmtNode*>(IA).Addr->getCode(); auto getOpNum = [MI] (MachineOperand &Op) -> unsigned { for (unsigned i = 0, n = MI->getNumOperands(); i != n; ++i) if (&MI->getOperand(i) == &Op) return i; llvm_unreachable("Invalid operand"); }; DenseMap<NodeId,unsigned> OpMap; NodeList Refs = IA.Addr->members(getDFG()); for (NodeAddr<RefNode*> RA : Refs) OpMap.insert(std::make_pair(RA.Id, getOpNum(RA.Addr->getOp()))); MI->RemoveOperand(OpNum); for (NodeAddr<RefNode*> RA : Refs) { unsigned N = OpMap[RA.Id]; if (N < OpNum) RA.Addr->setRegRef(&MI->getOperand(N)); else if (N > OpNum) RA.Addr->setRegRef(&MI->getOperand(N-1)); } }
/// Collect all the loop live out values in the map that maps original live out /// value to live out value in the cloned loop. static void collectLoopLiveOutValues( DenseMap<SILValue, SmallVector<SILValue, 8>> &LoopLiveOutValues, SILLoop *Loop, DenseMap<SILValue, SILValue> &ClonedValues) { for (auto *Block : Loop->getBlocks()) { // Look at block arguments. for (auto *Arg : Block->getArguments()) { for (auto *Op : Arg->getUses()) { // Is this use outside the loop? if (!Loop->contains(Op->getUser())) { auto ArgumentValue = SILValue(Arg); assert(ClonedValues.count(ArgumentValue) && "Unmapped Argument!"); if (!LoopLiveOutValues.count(ArgumentValue)) LoopLiveOutValues[ArgumentValue].push_back( ClonedValues[ArgumentValue]); } } } // And the instructions. for (auto &Inst : *Block) { for (SILValue result : Inst.getResults()) { for (auto *Op : result->getUses()) { // Ignore uses inside the loop. if (Loop->contains(Op->getUser())) continue; auto UsedValue = Op->get(); assert(UsedValue == result && "Instructions must match"); if (!LoopLiveOutValues.count(UsedValue)) LoopLiveOutValues[UsedValue].push_back(ClonedValues[result]); } } } } }
/// Resolve LinkOnce/Weak symbols. Record resolutions in the \p ResolvedODR map /// for caching, and in the \p Index for application during the ThinLTO /// backends. This is needed for correctness for exported symbols (ensure /// at least one copy kept) and a compile-time optimization (to drop duplicate /// copies when possible). static void resolveWeakForLinkerInIndex( ModuleSummaryIndex &Index, StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> &ResolvedODR) { DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy; computePrevailingCopies(Index, PrevailingCopy); auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) { const auto &Prevailing = PrevailingCopy.find(GUID); // Not in map means that there was only one copy, which must be prevailing. if (Prevailing == PrevailingCopy.end()) return true; return Prevailing->second == S; }; auto recordNewLinkage = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID, GlobalValue::LinkageTypes NewLinkage) { ResolvedODR[ModuleIdentifier][GUID] = NewLinkage; }; thinLTOResolveWeakForLinkerInIndex(Index, isPrevailing, recordNewLinkage); }
/// IsEquivalentPHI - Check if PHI has the same incoming value as specified /// in ValueMapping for each predecessor block. static bool IsEquivalentPHI(PHINode *PHI, DenseMap<BasicBlock*, Value*> &ValueMapping) { unsigned PHINumValues = PHI->getNumIncomingValues(); if (PHINumValues != ValueMapping.size()) return false; // Scan the phi to see if it matches. for (unsigned i = 0, e = PHINumValues; i != e; ++i) if (ValueMapping[PHI->getIncomingBlock(i)] != PHI->getIncomingValue(i)) { return false; } return true; }
// TODO: We should also visit ICmp, FCmp, GetElementPtr, Trunc, ZExt, SExt, // FPTrunc, FPExt, FPToUI, FPToSI, UIToFP, SIToFP, BitCast, Select, // ExtractElement, InsertElement, ShuffleVector, ExtractValue, InsertValue. // // Probaly it's worth to hoist the code for estimating the simplifications // effects to a separate class, since we have a very similar code in // InlineCost already. bool visitBinaryOperator(BinaryOperator &I) { Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); if (!isa<Constant>(LHS)) if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) LHS = SimpleLHS; if (!isa<Constant>(RHS)) if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) RHS = SimpleRHS; Value *SimpleV = nullptr; if (auto FI = dyn_cast<FPMathOperator>(&I)) SimpleV = SimplifyFPBinOp(I.getOpcode(), LHS, RHS, FI->getFastMathFlags()); else SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS); if (SimpleV && CountedInsns.insert(&I).second) NumberOfOptimizedInstructions += TTI.getUserCost(&I); if (Constant *C = dyn_cast_or_null<Constant>(SimpleV)) { SimplifiedValues[&I] = C; return true; } return false; }
bool PeepholeOptimizer::isMoveImmediate(MachineInstr *MI, SmallSet<unsigned, 4> &ImmDefRegs, DenseMap<unsigned, MachineInstr*> &ImmDefMIs) { const MCInstrDesc &MCID = MI->getDesc(); if (!MI->isMoveImmediate()) return false; if (MCID.getNumDefs() != 1) return false; unsigned Reg = MI->getOperand(0).getReg(); if (TargetRegisterInfo::isVirtualRegister(Reg)) { ImmDefMIs.insert(std::make_pair(Reg, MI)); ImmDefRegs.insert(Reg); return true; } return false; }
static CustomAttributesSet CacheAttributes(const Decl* D) { CustomAttributesSet attrs = {}; for (auto Attr : D->specific_attrs<AnnotateAttr>()) { auto annotation = Attr->getAnnotation(); #define ATTR(a) \ if (annotation == #a) { \ attrs.has_ ## a = true; \ } else #include "CustomAttributes.inc" #undef ATTR {} } const_cast<Decl*>(D)->dropAttr<AnnotateAttr>(); AttributesCache.insert(std::make_pair(D, attrs)); return attrs; }
/// assignInstructionRanges - Find ranges of instructions covered by each /// lexical scope. void LexicalScopes::assignInstructionRanges( SmallVectorImpl<InsnRange> &MIRanges, DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { LexicalScope *PrevLexicalScope = nullptr; for (const auto &R : MIRanges) { LexicalScope *S = MI2ScopeMap.lookup(R.first); assert(S && "Lost LexicalScope for a machine instruction!"); if (PrevLexicalScope && !PrevLexicalScope->dominates(S)) PrevLexicalScope->closeInsnRange(S); S->openInsnRange(R.first); S->extendInsnRange(R.second); PrevLexicalScope = S; } if (PrevLexicalScope) PrevLexicalScope->closeInsnRange(); }
/// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS nodes. /// COPY_TO_REGCLASS is just a normal copy, except that the destination /// register is constrained to be in a particular register class. /// void InstrEmitter::EmitCopyToRegClassNode(SDNode *Node, DenseMap<SDValue, unsigned> &VRBaseMap) { unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); // Create the new VReg in the destination class and emit a copy. unsigned DstRCIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); const TargetRegisterClass *DstRC = TRI->getRegClass(DstRCIdx); unsigned NewVReg = MRI->createVirtualRegister(DstRC); BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TargetOpcode::COPY), NewVReg).addReg(VReg); SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); }
// Given a list of loads that could be constant-folded (LoadBaseAddresses), // estimate number of optimized instructions after substituting the concrete // values for the given Iteration. // Fill in SimplifiedInsns map for future use in DCE-estimation. unsigned EstimateNumberOfSimplifiedInsns(unsigned Iteration) { SmallVector<Instruction *, 8> Worklist; SimplifiedValues.clear(); CountedInsns.clear(); NumberOfOptimizedInstructions = 0; // We start by adding all loads to the worklist. for (auto LoadDescr : LoadBaseAddresses) { LoadInst *LI = LoadDescr.first; SimplifiedValues[LI] = computeLoadValue(LI, Iteration); if (CountedInsns.insert(LI).second) NumberOfOptimizedInstructions += TTI.getUserCost(LI); for (auto U : LI->users()) { Instruction *UI = dyn_cast<Instruction>(U); if (!UI) continue; if (!L->contains(UI)) continue; Worklist.push_back(UI); } } // And then we try to simplify every user of every instruction from the // worklist. If we do simplify a user, add it to the worklist to process // its users as well. while (!Worklist.empty()) { Instruction *I = Worklist.pop_back_val(); if (!visit(I)) continue; for (auto U : I->users()) { Instruction *UI = dyn_cast<Instruction>(U); if (!UI) continue; if (!L->contains(UI)) continue; Worklist.push_back(UI); } } return NumberOfOptimizedInstructions; }
/// CloneDominatorInfo - Clone basicblock's dominator tree and, if available, /// dominance info. It is expected that basic block is already cloned. static void CloneDominatorInfo(BasicBlock *BB, DenseMap<const Value *, Value *> &ValueMap, DominatorTree *DT, DominanceFrontier *DF) { assert (DT && "DominatorTree is not available"); DenseMap<const Value *, Value*>::iterator BI = ValueMap.find(BB); assert (BI != ValueMap.end() && "BasicBlock clone is missing"); BasicBlock *NewBB = cast<BasicBlock>(BI->second); // NewBB already got dominator info. if (DT->getNode(NewBB)) return; assert (DT->getNode(BB) && "BasicBlock does not have dominator info"); // Entry block is not expected here. Infinite loops are not to cloned. assert (DT->getNode(BB)->getIDom() && "BasicBlock does not have immediate dominator"); BasicBlock *BBDom = DT->getNode(BB)->getIDom()->getBlock(); // NewBB's dominator is either BB's dominator or BB's dominator's clone. BasicBlock *NewBBDom = BBDom; DenseMap<const Value *, Value*>::iterator BBDomI = ValueMap.find(BBDom); if (BBDomI != ValueMap.end()) { NewBBDom = cast<BasicBlock>(BBDomI->second); if (!DT->getNode(NewBBDom)) CloneDominatorInfo(BBDom, ValueMap, DT, DF); } DT->addNewBlock(NewBB, NewBBDom); // Copy cloned dominance frontiner set if (DF) { DominanceFrontier::DomSetType NewDFSet; DominanceFrontier::iterator DFI = DF->find(BB); if ( DFI != DF->end()) { DominanceFrontier::DomSetType S = DFI->second; for (DominanceFrontier::DomSetType::iterator I = S.begin(), E = S.end(); I != E; ++I) { BasicBlock *DB = *I; DenseMap<const Value*, Value*>::iterator IDM = ValueMap.find(DB); if (IDM != ValueMap.end()) NewDFSet.insert(cast<BasicBlock>(IDM->second)); else NewDFSet.insert(DB); } } DF->addBasicBlock(NewBB, NewDFSet); } }
std::string getNodeLabel(const MachineBasicBlock *Node, const MachineBlockFrequencyInfo *Graph) { int layout_order = -1; // Attach additional ordering information if 'isSimple' is false. if (!isSimple()) { const MachineFunction *F = Node->getParent(); if (!CurFunc || F != CurFunc) { if (CurFunc) LayoutOrderMap.clear(); CurFunc = F; int O = 0; for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) { LayoutOrderMap[&*MBI] = O; } } layout_order = LayoutOrderMap[Node]; } return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(), layout_order); }
bool MIRParserImpl::initializeConstantPool( MachineConstantPool &ConstantPool, const yaml::MachineFunction &YamlMF, const MachineFunction &MF, DenseMap<unsigned, unsigned> &ConstantPoolSlots) { const auto &M = *MF.getFunction()->getParent(); SMDiagnostic Error; for (const auto &YamlConstant : YamlMF.Constants) { const Constant *Value = dyn_cast_or_null<Constant>( parseConstantValue(YamlConstant.Value.Value, Error, M)); if (!Value) return error(Error, YamlConstant.Value.SourceRange); unsigned Alignment = YamlConstant.Alignment ? YamlConstant.Alignment : M.getDataLayout().getPrefTypeAlignment(Value->getType()); // TODO: Report an error when the same constant pool value ID is redefined. ConstantPoolSlots.insert(std::make_pair( YamlConstant.ID, ConstantPool.getConstantPoolIndex(Value, Alignment))); } return false; }
/// assignInstructionRanges - Find ranges of instructions covered by each /// lexical scope. void LexicalScopes:: assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges, DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { LexicalScope *PrevLexicalScope = NULL; for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(), RE = MIRanges.end(); RI != RE; ++RI) { const InsnRange &R = *RI; LexicalScope *S = MI2ScopeMap.lookup(R.first); assert (S && "Lost LexicalScope for a machine instruction!"); if (PrevLexicalScope && !PrevLexicalScope->dominates(S)) PrevLexicalScope->closeInsnRange(S); S->openInsnRange(R.first); S->extendInsnRange(R.second); PrevLexicalScope = S; } if (PrevLexicalScope) PrevLexicalScope->closeInsnRange(); }
/// EmitRegSequence - Generate machine code for REG_SEQUENCE nodes. /// void InstrEmitter::EmitRegSequence(SDNode *Node, DenseMap<SDValue, unsigned> &VRBaseMap, bool IsClone, bool IsCloned) { unsigned DstRCIdx = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue(); const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx); unsigned NewVReg = MRI->createVirtualRegister(RC); MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), TII->get(TargetOpcode::REG_SEQUENCE), NewVReg); unsigned NumOps = Node->getNumOperands(); assert((NumOps & 1) == 1 && "REG_SEQUENCE must have an odd number of operands!"); const MCInstrDesc &II = TII->get(TargetOpcode::REG_SEQUENCE); for (unsigned i = 1; i != NumOps; ++i) { SDValue Op = Node->getOperand(i); if ((i & 1) == 0) { RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node->getOperand(i-1)); // Skip physical registers as they don't have a vreg to get and we'll // insert copies for them in TwoAddressInstructionPass anyway. if (!R || !TargetRegisterInfo::isPhysicalRegister(R->getReg())) { unsigned SubIdx = cast<ConstantSDNode>(Op)->getZExtValue(); unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap); const TargetRegisterClass *TRC = MRI->getRegClass(SubReg); const TargetRegisterClass *SRC = TRI->getMatchingSuperRegClass(RC, TRC, SubIdx); if (SRC && SRC != RC) { MRI->setRegClass(NewVReg, SRC); RC = SRC; } } } AddOperand(MI, Op, i+1, &II, VRBaseMap, /*IsDebug=*/false, IsClone, IsCloned); } MBB->insert(InsertPos, MI); SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; (void)isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); }
/// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS nodes. /// COPY_TO_REGCLASS is just a normal copy, except that the destination /// register is constrained to be in a particular register class. /// void InstrEmitter::EmitCopyToRegClassNode(SDNode *Node, DenseMap<SDValue, unsigned> &VRBaseMap) { unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); const TargetRegisterClass *SrcRC = MRI->getRegClass(VReg); unsigned DstRCIdx = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); const TargetRegisterClass *DstRC = TRI->getRegClass(DstRCIdx); // Create the new VReg in the destination class and emit a copy. unsigned NewVReg = MRI->createVirtualRegister(DstRC); bool Emitted = TII->copyRegToReg(*MBB, InsertPos, NewVReg, VReg, DstRC, SrcRC); assert(Emitted && "Unable to issue a copy instruction for a COPY_TO_REGCLASS node!\n"); (void) Emitted; SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, NewVReg)).second; isNew = isNew; // Silence compiler warning. assert(isNew && "Node emitted out of order - early"); }