void MemorySSAUpdater::wireOldPredecessorsToNewImmediatePredecessor( BasicBlock *Old, BasicBlock *New, ArrayRef<BasicBlock *> Preds) { assert(!MSSA->getWritableBlockAccesses(New) && "Access list should be null for a new block."); MemoryPhi *Phi = MSSA->getMemoryAccess(Old); if (!Phi) return; if (pred_size(Old) == 1) { assert(pred_size(New) == Preds.size() && "Should have moved all predecessors."); MSSA->moveTo(Phi, New, MemorySSA::Beginning); } else { assert(!Preds.empty() && "Must be moving at least one predecessor to the " "new immediate predecessor."); MemoryPhi *NewPhi = MSSA->createMemoryPhi(New); SmallPtrSet<BasicBlock *, 16> PredsSet(Preds.begin(), Preds.end()); Phi->unorderedDeleteIncomingIf([&](MemoryAccess *MA, BasicBlock *B) { if (PredsSet.count(B)) { NewPhi->addIncoming(MA, B); return true; } return false; }); Phi->addIncoming(NewPhi, New); if (onlySingleValue(NewPhi)) removeMemoryAccess(NewPhi); } }
// This is the marker algorithm from "Simple and Efficient Construction of // Static Single Assignment Form" // The simple, non-marker algorithm places phi nodes at any join // Here, we place markers, and only place phi nodes if they end up necessary. // They are only necessary if they break a cycle (IE we recursively visit // ourselves again), or we discover, while getting the value of the operands, // that there are two or more definitions needing to be merged. // This still will leave non-minimal form in the case of irreducible control // flow, where phi nodes may be in cycles with themselves, but unnecessary. MemoryAccess *MemorySSAUpdater::getPreviousDefRecursive(BasicBlock *BB) { // Single predecessor case, just recurse, we can only have one definition. if (BasicBlock *Pred = BB->getSinglePredecessor()) { return getPreviousDefFromEnd(Pred); } else if (VisitedBlocks.count(BB)) { // We hit our node again, meaning we had a cycle, we must insert a phi // node to break it so we have an operand. The only case this will // insert useless phis is if we have irreducible control flow. return MSSA->createMemoryPhi(BB); } else if (VisitedBlocks.insert(BB).second) { // Mark us visited so we can detect a cycle SmallVector<MemoryAccess *, 8> PhiOps; // Recurse to get the values in our predecessors for placement of a // potential phi node. This will insert phi nodes if we cycle in order to // break the cycle and have an operand. for (auto *Pred : predecessors(BB)) PhiOps.push_back(getPreviousDefFromEnd(Pred)); // Now try to simplify the ops to avoid placing a phi. // This may return null if we never created a phi yet, that's okay MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MSSA->getMemoryAccess(BB)); bool PHIExistsButNeedsUpdate = false; // See if the existing phi operands match what we need. // Unlike normal SSA, we only allow one phi node per block, so we can't just // create a new one. if (Phi && Phi->getNumOperands() != 0) if (!std::equal(Phi->op_begin(), Phi->op_end(), PhiOps.begin())) { PHIExistsButNeedsUpdate = true; } // See if we can avoid the phi by simplifying it. auto *Result = tryRemoveTrivialPhi(Phi, PhiOps); // If we couldn't simplify, we may have to create a phi if (Result == Phi) { if (!Phi) Phi = MSSA->createMemoryPhi(BB); // These will have been filled in by the recursive read we did above. if (PHIExistsButNeedsUpdate) { std::copy(PhiOps.begin(), PhiOps.end(), Phi->op_begin()); std::copy(pred_begin(BB), pred_end(BB), Phi->block_begin()); } else { unsigned i = 0; for (auto *Pred : predecessors(BB)) Phi->addIncoming(PhiOps[i++], Pred); } Result = Phi; } if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Result)) InsertedPHIs.push_back(MP); // Set ourselves up for the next variable by resetting visited state. VisitedBlocks.erase(BB); return Result; } llvm_unreachable("Should have hit one of the three cases above"); }
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; }
// This is the marker algorithm from "Simple and Efficient Construction of // Static Single Assignment Form" // The simple, non-marker algorithm places phi nodes at any join // Here, we place markers, and only place phi nodes if they end up necessary. // They are only necessary if they break a cycle (IE we recursively visit // ourselves again), or we discover, while getting the value of the operands, // that there are two or more definitions needing to be merged. // This still will leave non-minimal form in the case of irreducible control // flow, where phi nodes may be in cycles with themselves, but unnecessary. MemoryAccess *MemorySSAUpdater::getPreviousDefRecursive( BasicBlock *BB, DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> &CachedPreviousDef) { // First, do a cache lookup. Without this cache, certain CFG structures // (like a series of if statements) take exponential time to visit. auto Cached = CachedPreviousDef.find(BB); if (Cached != CachedPreviousDef.end()) { return Cached->second; } if (BasicBlock *Pred = BB->getSinglePredecessor()) { // Single predecessor case, just recurse, we can only have one definition. MemoryAccess *Result = getPreviousDefFromEnd(Pred, CachedPreviousDef); CachedPreviousDef.insert({BB, Result}); return Result; } if (VisitedBlocks.count(BB)) { // We hit our node again, meaning we had a cycle, we must insert a phi // node to break it so we have an operand. The only case this will // insert useless phis is if we have irreducible control flow. MemoryAccess *Result = MSSA->createMemoryPhi(BB); CachedPreviousDef.insert({BB, Result}); return Result; } if (VisitedBlocks.insert(BB).second) { // Mark us visited so we can detect a cycle SmallVector<TrackingVH<MemoryAccess>, 8> PhiOps; // Recurse to get the values in our predecessors for placement of a // potential phi node. This will insert phi nodes if we cycle in order to // break the cycle and have an operand. for (auto *Pred : predecessors(BB)) PhiOps.push_back(getPreviousDefFromEnd(Pred, CachedPreviousDef)); // Now try to simplify the ops to avoid placing a phi. // This may return null if we never created a phi yet, that's okay MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MSSA->getMemoryAccess(BB)); // See if we can avoid the phi by simplifying it. auto *Result = tryRemoveTrivialPhi(Phi, PhiOps); // If we couldn't simplify, we may have to create a phi if (Result == Phi) { if (!Phi) Phi = MSSA->createMemoryPhi(BB); // See if the existing phi operands match what we need. // Unlike normal SSA, we only allow one phi node per block, so we can't just // create a new one. if (Phi->getNumOperands() != 0) { // FIXME: Figure out whether this is dead code and if so remove it. if (!std::equal(Phi->op_begin(), Phi->op_end(), PhiOps.begin())) { // These will have been filled in by the recursive read we did above. std::copy(PhiOps.begin(), PhiOps.end(), Phi->op_begin()); std::copy(pred_begin(BB), pred_end(BB), Phi->block_begin()); } } else { unsigned i = 0; for (auto *Pred : predecessors(BB)) Phi->addIncoming(&*PhiOps[i++], Pred); InsertedPHIs.push_back(Phi); } Result = Phi; } // Set ourselves up for the next variable by resetting visited state. VisitedBlocks.erase(BB); CachedPreviousDef.insert({BB, Result}); return Result; } llvm_unreachable("Should have hit one of the three cases above"); }
// A brief description of the algorithm: // First, we compute what should define the new def, using the SSA // construction algorithm. // Then, we update the defs below us (and any new phi nodes) in the graph to // point to the correct new defs, to ensure we only have one variable, and no // disconnected stores. void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { InsertedPHIs.clear(); // See if we had a local def, and if not, go hunting. MemoryAccess *DefBefore = getPreviousDef(MD); bool DefBeforeSameBlock = DefBefore->getBlock() == MD->getBlock(); // There is a def before us, which means we can replace any store/phi uses // of that thing with us, since we are in the way of whatever was there // before. // We now define that def's memorydefs and memoryphis if (DefBeforeSameBlock) { for (auto UI = DefBefore->use_begin(), UE = DefBefore->use_end(); UI != UE;) { Use &U = *UI++; // Leave the uses alone if (isa<MemoryUse>(U.getUser())) continue; U.set(MD); } } // and that def is now our defining access. // We change them in this order otherwise we will appear in the use list // above and reset ourselves. MD->setDefiningAccess(DefBefore); SmallVector<WeakVH, 8> FixupList(InsertedPHIs.begin(), InsertedPHIs.end()); if (!DefBeforeSameBlock) { // If there was a local def before us, we must have the same effect it // did. Because every may-def is the same, any phis/etc we would create, it // would also have created. If there was no local def before us, we // performed a global update, and have to search all successors and make // sure we update the first def in each of them (following all paths until // we hit the first def along each path). This may also insert phi nodes. // TODO: There are other cases we can skip this work, such as when we have a // single successor, and only used a straight line of single pred blocks // backwards to find the def. To make that work, we'd have to track whether // getDefRecursive only ever used the single predecessor case. These types // of paths also only exist in between CFG simplifications. FixupList.push_back(MD); } while (!FixupList.empty()) { unsigned StartingPHISize = InsertedPHIs.size(); fixupDefs(FixupList); FixupList.clear(); // Put any new phis on the fixup list, and process them FixupList.append(InsertedPHIs.begin() + StartingPHISize, InsertedPHIs.end()); } // Now that all fixups are done, rename all uses if we are asked. if (RenameUses) { SmallPtrSet<BasicBlock *, 16> Visited; BasicBlock *StartBlock = MD->getBlock(); // We are guaranteed there is a def in the block, because we just got it // handed to us in this function. MemoryAccess *FirstDef = &*MSSA->getWritableBlockDefs(StartBlock)->begin(); // Convert to incoming value if it's a memorydef. A phi *is* already an // incoming value. if (auto *MD = dyn_cast<MemoryDef>(FirstDef)) FirstDef = MD->getDefiningAccess(); MSSA->renamePass(MD->getBlock(), FirstDef, Visited); // We just inserted a phi into this block, so the incoming value will become // the phi anyway, so it does not matter what we pass. for (auto &MP : InsertedPHIs) { MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MP); if (Phi) MSSA->renamePass(Phi->getBlock(), nullptr, Visited); } } }