10b57cec5SDimitry Andric //===- DemoteRegToStack.cpp - Move a virtual register to the stack --------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 100b57cec5SDimitry Andric #include "llvm/Analysis/CFG.h" 11*0fca6ea1SDimitry Andric #include "llvm/IR/DataLayout.h" 120b57cec5SDimitry Andric #include "llvm/IR/Function.h" 130b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 140b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 1581ad6265SDimitry Andric #include "llvm/Transforms/Utils/Local.h" 160b57cec5SDimitry Andric using namespace llvm; 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric /// DemoteRegToStack - This function takes a virtual register computed by an 190b57cec5SDimitry Andric /// Instruction and replaces it with a slot in the stack frame, allocated via 200b57cec5SDimitry Andric /// alloca. This allows the CFG to be changed around without fear of 210b57cec5SDimitry Andric /// invalidating the SSA information for the value. It returns the pointer to 220b57cec5SDimitry Andric /// the alloca inserted to create a stack slot for I. 230b57cec5SDimitry Andric AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads, 24*0fca6ea1SDimitry Andric std::optional<BasicBlock::iterator> AllocaPoint) { 250b57cec5SDimitry Andric if (I.use_empty()) { 260b57cec5SDimitry Andric I.eraseFromParent(); 270b57cec5SDimitry Andric return nullptr; 280b57cec5SDimitry Andric } 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric Function *F = I.getParent()->getParent(); 31*0fca6ea1SDimitry Andric const DataLayout &DL = F->getDataLayout(); 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric // Create a stack slot to hold the value. 340b57cec5SDimitry Andric AllocaInst *Slot; 350b57cec5SDimitry Andric if (AllocaPoint) { 360b57cec5SDimitry Andric Slot = new AllocaInst(I.getType(), DL.getAllocaAddrSpace(), nullptr, 37*0fca6ea1SDimitry Andric I.getName()+".reg2mem", *AllocaPoint); 380b57cec5SDimitry Andric } else { 390b57cec5SDimitry Andric Slot = new AllocaInst(I.getType(), DL.getAllocaAddrSpace(), nullptr, 40*0fca6ea1SDimitry Andric I.getName() + ".reg2mem", F->getEntryBlock().begin()); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // We cannot demote invoke instructions to the stack if their normal edge 440b57cec5SDimitry Andric // is critical. Therefore, split the critical edge and create a basic block 450b57cec5SDimitry Andric // into which the store can be inserted. 460b57cec5SDimitry Andric if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) { 470b57cec5SDimitry Andric if (!II->getNormalDest()->getSinglePredecessor()) { 480b57cec5SDimitry Andric unsigned SuccNum = GetSuccessorNumber(II->getParent(), II->getNormalDest()); 490b57cec5SDimitry Andric assert(isCriticalEdge(II, SuccNum) && "Expected a critical edge!"); 500b57cec5SDimitry Andric BasicBlock *BB = SplitCriticalEdge(II, SuccNum); 510b57cec5SDimitry Andric assert(BB && "Unable to split critical edge."); 520b57cec5SDimitry Andric (void)BB; 530b57cec5SDimitry Andric } 54*0fca6ea1SDimitry Andric } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) { 55*0fca6ea1SDimitry Andric for (unsigned i = 0; i < CBI->getNumSuccessors(); i++) { 56*0fca6ea1SDimitry Andric auto *Succ = CBI->getSuccessor(i); 57*0fca6ea1SDimitry Andric if (!Succ->getSinglePredecessor()) { 58*0fca6ea1SDimitry Andric assert(isCriticalEdge(II, i) && "Expected a critical edge!"); 59*0fca6ea1SDimitry Andric [[maybe_unused]] BasicBlock *BB = SplitCriticalEdge(II, i); 60*0fca6ea1SDimitry Andric assert(BB && "Unable to split critical edge."); 61*0fca6ea1SDimitry Andric } 62*0fca6ea1SDimitry Andric } 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // Change all of the users of the instruction to read from the stack slot. 660b57cec5SDimitry Andric while (!I.use_empty()) { 670b57cec5SDimitry Andric Instruction *U = cast<Instruction>(I.user_back()); 680b57cec5SDimitry Andric if (PHINode *PN = dyn_cast<PHINode>(U)) { 690b57cec5SDimitry Andric // If this is a PHI node, we can't insert a load of the value before the 700b57cec5SDimitry Andric // use. Instead insert the load in the predecessor block corresponding 710b57cec5SDimitry Andric // to the incoming value. 720b57cec5SDimitry Andric // 730b57cec5SDimitry Andric // Note that if there are multiple edges from a basic block to this PHI 740b57cec5SDimitry Andric // node that we cannot have multiple loads. The problem is that the 750b57cec5SDimitry Andric // resulting PHI node will have multiple values (from each load) coming in 760b57cec5SDimitry Andric // from the same block, which is illegal SSA form. For this reason, we 770b57cec5SDimitry Andric // keep track of and reuse loads we insert. 780b57cec5SDimitry Andric DenseMap<BasicBlock*, Value*> Loads; 790b57cec5SDimitry Andric for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 800b57cec5SDimitry Andric if (PN->getIncomingValue(i) == &I) { 810b57cec5SDimitry Andric Value *&V = Loads[PN->getIncomingBlock(i)]; 820b57cec5SDimitry Andric if (!V) { 830b57cec5SDimitry Andric // Insert the load into the predecessor block 840b57cec5SDimitry Andric V = new LoadInst(I.getType(), Slot, I.getName() + ".reload", 850b57cec5SDimitry Andric VolatileLoads, 86*0fca6ea1SDimitry Andric PN->getIncomingBlock(i)->getTerminator()->getIterator()); 8706c3fb27SDimitry Andric Loads[PN->getIncomingBlock(i)] = V; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric PN->setIncomingValue(i, V); 900b57cec5SDimitry Andric } 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric } else { 930b57cec5SDimitry Andric // If this is a normal instruction, just insert a load. 940b57cec5SDimitry Andric Value *V = new LoadInst(I.getType(), Slot, I.getName() + ".reload", 95*0fca6ea1SDimitry Andric VolatileLoads, U->getIterator()); 960b57cec5SDimitry Andric U->replaceUsesOfWith(&I, V); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // Insert stores of the computed value into the stack slot. We have to be 1010b57cec5SDimitry Andric // careful if I is an invoke instruction, because we can't insert the store 1020b57cec5SDimitry Andric // AFTER the terminator instruction. 1030b57cec5SDimitry Andric BasicBlock::iterator InsertPt; 1040b57cec5SDimitry Andric if (!I.isTerminator()) { 1050b57cec5SDimitry Andric InsertPt = ++I.getIterator(); 106bdd1243dSDimitry Andric // Don't insert before PHI nodes or landingpad instrs. 1070b57cec5SDimitry Andric for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt) 108bdd1243dSDimitry Andric if (isa<CatchSwitchInst>(InsertPt)) 109bdd1243dSDimitry Andric break; 110bdd1243dSDimitry Andric if (isa<CatchSwitchInst>(InsertPt)) { 111bdd1243dSDimitry Andric for (BasicBlock *Handler : successors(&*InsertPt)) 112*0fca6ea1SDimitry Andric new StoreInst(&I, Slot, Handler->getFirstInsertionPt()); 113bdd1243dSDimitry Andric return Slot; 114bdd1243dSDimitry Andric } 115*0fca6ea1SDimitry Andric } else if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) { 116*0fca6ea1SDimitry Andric InsertPt = II->getNormalDest()->getFirstInsertionPt(); 117*0fca6ea1SDimitry Andric } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) { 118*0fca6ea1SDimitry Andric for (BasicBlock *Succ : successors(CBI)) 119*0fca6ea1SDimitry Andric new StoreInst(CBI, Slot, Succ->getFirstInsertionPt()); 120*0fca6ea1SDimitry Andric return Slot; 1210b57cec5SDimitry Andric } else { 122*0fca6ea1SDimitry Andric llvm_unreachable("Unsupported terminator for Reg2Mem"); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 125*0fca6ea1SDimitry Andric new StoreInst(&I, Slot, InsertPt); 1260b57cec5SDimitry Andric return Slot; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric /// DemotePHIToStack - This function takes a virtual register computed by a PHI 1300b57cec5SDimitry Andric /// node and replaces it with a slot in the stack frame allocated via alloca. 1310b57cec5SDimitry Andric /// The PHI node is deleted. It returns the pointer to the alloca inserted. 132*0fca6ea1SDimitry Andric AllocaInst *llvm::DemotePHIToStack(PHINode *P, std::optional<BasicBlock::iterator> AllocaPoint) { 1330b57cec5SDimitry Andric if (P->use_empty()) { 1340b57cec5SDimitry Andric P->eraseFromParent(); 1350b57cec5SDimitry Andric return nullptr; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 138*0fca6ea1SDimitry Andric const DataLayout &DL = P->getDataLayout(); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric // Create a stack slot to hold the value. 1410b57cec5SDimitry Andric AllocaInst *Slot; 1420b57cec5SDimitry Andric if (AllocaPoint) { 1430b57cec5SDimitry Andric Slot = new AllocaInst(P->getType(), DL.getAllocaAddrSpace(), nullptr, 144*0fca6ea1SDimitry Andric P->getName()+".reg2mem", *AllocaPoint); 1450b57cec5SDimitry Andric } else { 1460b57cec5SDimitry Andric Function *F = P->getParent()->getParent(); 1470b57cec5SDimitry Andric Slot = new AllocaInst(P->getType(), DL.getAllocaAddrSpace(), nullptr, 1480b57cec5SDimitry Andric P->getName() + ".reg2mem", 149*0fca6ea1SDimitry Andric F->getEntryBlock().begin()); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric // Iterate over each operand inserting a store in each predecessor. 1530b57cec5SDimitry Andric for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) { 1540b57cec5SDimitry Andric if (InvokeInst *II = dyn_cast<InvokeInst>(P->getIncomingValue(i))) { 1550b57cec5SDimitry Andric assert(II->getParent() != P->getIncomingBlock(i) && 1560b57cec5SDimitry Andric "Invoke edge not supported yet"); (void)II; 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric new StoreInst(P->getIncomingValue(i), Slot, 159*0fca6ea1SDimitry Andric P->getIncomingBlock(i)->getTerminator()->getIterator()); 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric // Insert a load in place of the PHI and replace all uses. 1630b57cec5SDimitry Andric BasicBlock::iterator InsertPt = P->getIterator(); 164bdd1243dSDimitry Andric // Don't insert before PHI nodes or landingpad instrs. 1650b57cec5SDimitry Andric for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt) 166bdd1243dSDimitry Andric if (isa<CatchSwitchInst>(InsertPt)) 167bdd1243dSDimitry Andric break; 168bdd1243dSDimitry Andric if (isa<CatchSwitchInst>(InsertPt)) { 169bdd1243dSDimitry Andric // We need a separate load before each actual use of the PHI 170bdd1243dSDimitry Andric SmallVector<Instruction *, 4> Users; 171bdd1243dSDimitry Andric for (User *U : P->users()) { 172bdd1243dSDimitry Andric Instruction *User = cast<Instruction>(U); 173bdd1243dSDimitry Andric Users.push_back(User); 174bdd1243dSDimitry Andric } 175bdd1243dSDimitry Andric for (Instruction *User : Users) { 176bdd1243dSDimitry Andric Value *V = 177*0fca6ea1SDimitry Andric new LoadInst(P->getType(), Slot, P->getName() + ".reload", User->getIterator()); 178bdd1243dSDimitry Andric User->replaceUsesOfWith(P, V); 179bdd1243dSDimitry Andric } 180bdd1243dSDimitry Andric } else { 1810b57cec5SDimitry Andric Value *V = 182*0fca6ea1SDimitry Andric new LoadInst(P->getType(), Slot, P->getName() + ".reload", InsertPt); 1830b57cec5SDimitry Andric P->replaceAllUsesWith(V); 184bdd1243dSDimitry Andric } 1850b57cec5SDimitry Andric // Delete PHI. 1860b57cec5SDimitry Andric P->eraseFromParent(); 1870b57cec5SDimitry Andric return Slot; 1880b57cec5SDimitry Andric } 189