static bool MaybeRewriteToFallthrough(MachineInstr &MI, MachineBasicBlock &MBB, const MachineFunction &MF, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo &TII, unsigned FallthroughOpc, unsigned CopyLocalOpc) { if (DisableWebAssemblyFallthroughReturnOpt) return false; if (&MBB != &MF.back()) return false; if (&MI != &MBB.back()) return false; // If the operand isn't stackified, insert a COPY to read the operand and // stackify it. MachineOperand &MO = MI.getOperand(0); unsigned Reg = MO.getReg(); if (!MFI.isVRegStackified(Reg)) { unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg)); BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(CopyLocalOpc), NewReg) .addReg(Reg); MO.setReg(NewReg); MFI.stackifyVReg(NewReg); } // Rewrite the return. MI.setDesc(TII.get(FallthroughOpc)); return true; }
bool VPreRegAllocSched::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); MRI = &MF.getRegInfo(); FInfo = MF.getInfo<VFInfo>(); AA = &getAnalysis<AliasAnalysis>(); MLI = &getAnalysis<MachineLoopInfo>(); MDT= &getAnalysis<MachineDominatorTree>(); LI = &getAnalysis<LoopInfo>(); SE = &getAnalysis<ScalarEvolution>(); // Create a place holder for the virtual exit for the scheduling graph. MachineBasicBlock *VirtualExit = MF.CreateMachineBasicBlock(); MF.push_back(VirtualExit); VSchedGraph G(getAnalysis<DetialLatencyInfo>(), EnableDangling, false, 1); buildGlobalSchedulingGraph(G, &MF.front(), VirtualExit); schedule(G); DEBUG(G.viewCPGraph()); DEBUG(G.viewDPGraph()); // Erase the virtual exit block. VirtualExit->eraseFromParent(); MF.RenumberBlocks(&MF.back()); unsigned TotalCycles = G.emitSchedule(); FInfo->setTotalSlots(TotalCycles); cleanUpSchedule(); return true; }
static void interruptFrameLayout(MachineFunction &MF) { const Function *F = MF.getFunction(); llvm::CallingConv::ID CallConv = F->getCallingConv(); // If this function is not using either the interrupt_handler // calling convention or the save_volatiles calling convention // then we don't need to do any additional frame layout. if (CallConv != llvm::CallingConv::MBLAZE_INTR && CallConv != llvm::CallingConv::MBLAZE_SVOL) return; MachineFrameInfo *MFI = MF.getFrameInfo(); const MachineRegisterInfo &MRI = MF.getRegInfo(); const MBlazeInstrInfo &TII = *static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo()); // Determine if the calling convention is the interrupt_handler // calling convention. Some pieces of the prologue and epilogue // only need to be emitted if we are lowering and interrupt handler. bool isIntr = CallConv == llvm::CallingConv::MBLAZE_INTR; // Determine where to put prologue and epilogue additions MachineBasicBlock &MENT = MF.front(); MachineBasicBlock &MEXT = MF.back(); MachineBasicBlock::iterator MENTI = MENT.begin(); MachineBasicBlock::iterator MEXTI = prior(MEXT.end()); DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc(); DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc(); // Store the frame indexes generated during prologue additions for use // when we are generating the epilogue additions. SmallVector<int, 10> VFI; // Build the prologue SWI for R3 - R12 if needed. Note that R11 must // always have a SWI because it is used when processing RMSR. for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) { if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue; int FI = MFI->CreateStackObject(4,4,false,false); VFI.push_back(FI); BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r) .addFrameIndex(FI).addImm(0); } // Build the prologue SWI for R17, R18 int R17FI = MFI->CreateStackObject(4,4,false,false); int R18FI = MFI->CreateStackObject(4,4,false,false); BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17) .addFrameIndex(R17FI).addImm(0); BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18) .addFrameIndex(R18FI).addImm(0); // Buid the prologue SWI and the epilogue LWI for RMSR if needed if (isIntr) { int MSRFI = MFI->CreateStackObject(4,4,false,false); BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11) .addReg(MBlaze::RMSR); BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11) .addFrameIndex(MSRFI).addImm(0); BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11) .addFrameIndex(MSRFI).addImm(0); BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR) .addReg(MBlaze::R11); } // Build the epilogue LWI for R17, R18 BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18) .addFrameIndex(R18FI).addImm(0); BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17) .addFrameIndex(R17FI).addImm(0); // Build the epilogue LWI for R3 - R12 if needed for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) { if (!MRI.isPhysRegUsed(r)) continue; BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r) .addFrameIndex(VFI[--i]).addImm(0); } }