bool mssa::runOnFunction(Function &F) { MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA(); //MemorySSAWalker MAW = new MemorySSAWalker(MSSA); errs()<<"\n"; for (Function::iterator BB = F.begin(); BB != F.end(); BB++){ errs() << "Basic block (name=" << BB->getName() << ")\n"; //Get MemoryPhi and print it out MemoryPhi* MP = MSSA->getMemoryAccess(dyn_cast<BasicBlock>(BB)); if (MP != NULL) MP->dump(); for (BasicBlock::iterator itrIns = (*BB).begin(); itrIns != (*BB).end(); itrIns++) { //MemoryAccess* MA = MAW.getClobberingMemoryAccess(itrIns); //MemoryLocation Location; //MemoryAccess* MAR = MAW.getClobberingMemoryAccess(MA,&Location); //MAR->dump(); errs()<<"Instruction: "<< *itrIns <<"\n"; //Get MemoryDef or MemoryUse and print it out MemoryAccess *MA = MSSA->getMemoryAccess(dyn_cast<Value>(itrIns)); if (MA != NULL) { MA->dump(); //if(MSSA->isLiveOnEntryDef(MA)) //Get immediate MemoryDef of the instruction annotated MemoryDef/MemoryUse for (memoryaccess_def_iterator MAitr = MA->defs_begin(); MAitr != MA->defs_end(); MAitr++) { errs()<<"Def: "<<**MAitr<<"\n"; //Get the instruction the immediate Memory Def annotation represent Instruction* u = cast<MemoryUseOrDef>(*MAitr)->getMemoryInst(); if (u != NULL) errs()<<" Def Inst: "<<*u<<"\n"; } } } } return 0; }
static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, const TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU) { const DataLayout &DL = L.getHeader()->getModule()->getDataLayout(); SimplifyQuery SQ(DL, &TLI, &DT, &AC); // On the first pass over the loop body we try to simplify every instruction. // On subsequent passes, we can restrict this to only simplifying instructions // where the inputs have been updated. We end up needing two sets: one // containing the instructions we are simplifying in *this* pass, and one for // the instructions we will want to simplify in the *next* pass. We use // pointers so we can swap between two stably allocated sets. SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2; // Track the PHI nodes that have already been visited during each iteration so // that we can identify when it is necessary to iterate. SmallPtrSet<PHINode *, 4> VisitedPHIs; // While simplifying we may discover dead code or cause code to become dead. // Keep track of all such instructions and we will delete them at the end. SmallVector<Instruction *, 8> DeadInsts; // First we want to create an RPO traversal of the loop body. By processing in // RPO we can ensure that definitions are processed prior to uses (for non PHI // uses) in all cases. This ensures we maximize the simplifications in each // iteration over the loop and minimizes the possible causes for continuing to // iterate. LoopBlocksRPO RPOT(&L); RPOT.perform(&LI); MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr; bool Changed = false; for (;;) { if (MSSAU && VerifyMemorySSA) MSSA->verifyMemorySSA(); for (BasicBlock *BB : RPOT) { for (Instruction &I : *BB) { if (auto *PI = dyn_cast<PHINode>(&I)) VisitedPHIs.insert(PI); if (I.use_empty()) { if (isInstructionTriviallyDead(&I, &TLI)) DeadInsts.push_back(&I); continue; } // We special case the first iteration which we can detect due to the // empty `ToSimplify` set. bool IsFirstIteration = ToSimplify->empty(); if (!IsFirstIteration && !ToSimplify->count(&I)) continue; Value *V = SimplifyInstruction(&I, SQ.getWithInstruction(&I)); if (!V || !LI.replacementPreservesLCSSAForm(&I, V)) continue; for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); UI != UE;) { Use &U = *UI++; auto *UserI = cast<Instruction>(U.getUser()); U.set(V); // If the instruction is used by a PHI node we have already processed // we'll need to iterate on the loop body to converge, so add it to // the next set. if (auto *UserPI = dyn_cast<PHINode>(UserI)) if (VisitedPHIs.count(UserPI)) { Next->insert(UserPI); continue; } // If we are only simplifying targeted instructions and the user is an // instruction in the loop body, add it to our set of targeted // instructions. Because we process defs before uses (outside of PHIs) // we won't have visited it yet. // // We also skip any uses outside of the loop being simplified. Those // should always be PHI nodes due to LCSSA form, and we don't want to // try to simplify those away. assert((L.contains(UserI) || isa<PHINode>(UserI)) && "Uses outside the loop should be PHI nodes due to LCSSA!"); if (!IsFirstIteration && L.contains(UserI)) ToSimplify->insert(UserI); } if (MSSAU) if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V)) if (MemoryAccess *MA = MSSA->getMemoryAccess(&I)) if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI)) MA->replaceAllUsesWith(ReplacementMA); assert(I.use_empty() && "Should always have replaced all uses!"); if (isInstructionTriviallyDead(&I, &TLI)) DeadInsts.push_back(&I); ++NumSimplified; Changed = true; } } // Delete any dead instructions found thus far now that we've finished an // iteration over all instructions in all the loop blocks. if (!DeadInsts.empty()) { Changed = true; RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU); } if (MSSAU && VerifyMemorySSA) MSSA->verifyMemorySSA(); // If we never found a PHI that needs to be simplified in the next // iteration, we're done. if (Next->empty()) break; // Otherwise, put the next set in place for the next iteration and reset it // and the visited PHIs for that iteration. std::swap(Next, ToSimplify); Next->clear(); VisitedPHIs.clear(); DeadInsts.clear(); } return Changed; }