From 330799028bc3f2881a33112d9c1956b8ee93c111 Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Fri, 6 Mar 2020 21:14:11 +0300 Subject: [PATCH 1/9] Change control flow generation scheme --- llvm/lib/CodeGen/TailDuplicator.cpp | 2 + llvm/lib/Target/TVM/CMakeLists.txt | 2 - llvm/lib/Target/TVM/TVM.h | 4 - llvm/lib/Target/TVM/TVMAsmPrinter.cpp | 147 ++---- llvm/lib/Target/TVM/TVMContinuationsHoist.cpp | 170 ------ .../lib/Target/TVM/TVMControlFlowInstrInfo.td | 9 - llvm/lib/Target/TVM/TVMISelLowering.cpp | 82 +-- llvm/lib/Target/TVM/TVMISelLowering.h | 7 - llvm/lib/Target/TVM/TVMInstrInfo.cpp | 107 +--- llvm/lib/Target/TVM/TVMMachineFunctionInfo.h | 14 - llvm/lib/Target/TVM/TVMPeephole.cpp | 486 ------------------ llvm/lib/Target/TVM/TVMStackBlockInfo.h | 9 + llvm/lib/Target/TVM/TVMStackModel.cpp | 55 +- llvm/lib/Target/TVM/TVMTargetMachine.cpp | 9 - llvm/test/CodeGen/TVM/cfg.ll | 78 ++- llvm/test/CodeGen/TVM/hiddenstack.ll | 1 + llvm/test/CodeGen/TVM/load-store-local.ll | 1 - llvm/test/CodeGen/TVM/loops.ll | 96 +++- llvm/test/CodeGen/TVM/optimizations/ifelse.ll | 31 -- .../TVM/optimizations/pushcont_inline.ll | 78 --- llvm/test/CodeGen/TVM/ret_nested.ll | 90 ---- 21 files changed, 276 insertions(+), 1202 deletions(-) delete mode 100644 llvm/lib/Target/TVM/TVMContinuationsHoist.cpp delete mode 100644 llvm/lib/Target/TVM/TVMPeephole.cpp delete mode 100644 llvm/test/CodeGen/TVM/optimizations/ifelse.ll delete mode 100644 llvm/test/CodeGen/TVM/optimizations/pushcont_inline.ll delete mode 100644 llvm/test/CodeGen/TVM/ret_nested.ll diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp index b118c176a897..d114e0726123 100644 --- a/llvm/lib/CodeGen/TailDuplicator.cpp +++ b/llvm/lib/CodeGen/TailDuplicator.cpp @@ -747,10 +747,12 @@ bool TailDuplicator::duplicateSimpleBB( } // Avoid adding fall through branches. + if (TII->canFallthrough(*PredFBB, *NextBB)) { // TVM local if (PredFBB == NextBB) PredFBB = nullptr; if (PredTBB == NextBB && PredFBB == nullptr) PredTBB = nullptr; + } auto DL = PredBB->findBranchDebugLoc(); TII->removeBranch(*PredBB); diff --git a/llvm/lib/Target/TVM/CMakeLists.txt b/llvm/lib/Target/TVM/CMakeLists.txt index 35bb8cf3ba43..933e2de096c0 100644 --- a/llvm/lib/Target/TVM/CMakeLists.txt +++ b/llvm/lib/Target/TVM/CMakeLists.txt @@ -31,14 +31,12 @@ add_llvm_target(TVMCodeGen TVMReplacePhysRegs.cpp TVMRegStackify.cpp TVMRegNumbering.cpp - TVMPeephole.cpp TVMStack.cpp TVMStackBlockInfo.cpp TVMStackFixup.cpp TVMStackPatterns.cpp TVMStackModel.cpp TVMUtilities.cpp - TVMContinuationsHoist.cpp TVMLoadStoreReplace.cpp TVMIfConversionTerm.cpp ) diff --git a/llvm/lib/Target/TVM/TVM.h b/llvm/lib/Target/TVM/TVM.h index 01dad8f0cf40..1844ee1a8f84 100644 --- a/llvm/lib/Target/TVM/TVM.h +++ b/llvm/lib/Target/TVM/TVM.h @@ -34,11 +34,9 @@ FunctionPass *createTVMPrepareForLiveIntervals(); FunctionPass *createTVMRematerialize(); FunctionPass *createTVMRegStackify(); FunctionPass *createTVMRegNumbering(); -FunctionPass *createTVMPeephole(); FunctionPass *createTVMStackModel(); FunctionPass *createTVMLoopInstructions(); FunctionPass *createTVMLoopPrepare(); -FunctionPass *createTVMContinuationsHoist(); FunctionPass *createTVMIfConversionTerm(); BasicBlockPass *createTVMLoadStoreReplace(); @@ -49,11 +47,9 @@ void initializeTVMPrepareForLiveIntervalsPass(PassRegistry &); void initializeTVMRematerializePass(PassRegistry &); void initializeTVMRegStackifyPass(PassRegistry &); void initializeTVMRegNumberingPass(PassRegistry &); -void initializeTVMPeepholePass(PassRegistry &); void initializeTVMStackModelPass(PassRegistry &); void initializeTVMLoopInstructionsPass(PassRegistry &); void initializeTVMLoopPreparePass(PassRegistry &); -void initializeTVMContinuationsHoistPass(PassRegistry &); void initializeTVMLoadStoreReplacePass(PassRegistry &); void initializeTVMIfConversionTermPass(PassRegistry &); diff --git a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp index a423bc88a9a5..d15e48e535da 100644 --- a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp +++ b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp @@ -49,9 +49,10 @@ class TVMAsmPrinter : public AsmPrinter { void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, const char *Modifier = nullptr); void EmitInstruction(const MachineInstr *MI) override; - bool ShouldPrintNextBlock(const MachineBasicBlock &CurMBB) const override; std::string regToString(const MachineOperand &MO); void EmitBasicBlockStart(const MachineBasicBlock &MBB) const override; + void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override; + void EmitFunctionBodyEnd() override; void EmitFunctionHeader() override; @@ -59,10 +60,6 @@ class TVMAsmPrinter : public AsmPrinter { void EmitBigInt(const ConstantInt *CI) override; bool runOnMachineFunction(MachineFunction &MF) override; -protected: - void EmitSubBlockForPushcont(const TVMMCInstLower &lower, const MCInst &Inst, - int depth); - void EmitBBEntry(const MachineBasicBlock &MBB) const; private: TVMFunctionInfo *MFI; }; @@ -97,7 +94,7 @@ void TVMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, //===----------------------------------------------------------------------===// void TVMAsmPrinter::EmitInstruction(const MachineInstr *MI) { - LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI << '\n'); + LLVM_DEBUG(dbgs() << "EmitInstruction: " << *MI); if (isVerbose()) for (auto Comment : MFI->getStackModelComments(MI)) { OutStreamer->AddComment(Comment); @@ -131,112 +128,72 @@ void TVMAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; MCInstLowering.lower(MI, TmpInst); - // We need to access OutStreamer->GetOS() to have such code pattern: - // (tabs for first offset from labels ans 2-spaces nested PUSHCONTs) - // \tInstr1 - // \tInstr2 - // \tPUSHCONT - // \t{ - // \t Instr3 - // \t Instr4 - // \t PUSHCONT - // \t { - // \t Instr5 - // \t Instr6 - // \t } - // \t} - OutStreamer->GetOS() << "\t"; + OutStreamer->GetOS() << (MF->size() < 2 ? " " : " "); EmitToStreamer(*OutStreamer, TmpInst); - if (TmpInst.getOpcode() == TVM::PUSHCONT_MBB_S) { - EmitSubBlockForPushcont(MCInstLowering, TmpInst, 0); - } } } -bool TVMAsmPrinter::ShouldPrintNextBlock(const MachineBasicBlock &CurMBB) const { - auto Term = CurMBB.terminators(); - // Continue if no terminators or fallthrough terminator - if (Term.begin() == Term.end() || - Term.begin()->getOpcode() == TVM::IFJMP_S || - Term.begin()->getOpcode() == TVM::IFNOTJMP_S) - return true; - return false; +void TVMAsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { + if (MF->size() < 2) + return; + OutStreamer->AddComment(MBB.getName()); + OutStreamer->EmitRawText(" PUSHCONT {"); } -void TVMAsmPrinter::EmitBBEntry(const MachineBasicBlock &MBB) const { - if (isVerbose()) { - if (const BasicBlock *BB = MBB.getBasicBlock()) { - if (BB->hasName()) { - BB->printAsOperand(OutStreamer->GetCommentOS(), false, BB->getModule()); - OutStreamer->GetCommentOS() << '\n'; - } - } - auto BBStackComment = MFI->getStackModelBBComment(&MBB); - if (!BBStackComment.empty()) - OutStreamer->AddComment(BBStackComment, true); - } - OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":", false); +void TVMAsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) { + if (MF->size() < 2) + return; + OutStreamer->EmitRawText(" }"); } -void TVMAsmPrinter::EmitSubBlockForPushcont(const TVMMCInstLower &lower, - const MCInst &Inst, - int depth) { - OutStreamer->EmitRawText("\t" + std::string(depth, ' ') + "{\n"); +void TVMAsmPrinter::EmitFunctionHeader() { + const Function &F = MF->getFunction(); + if (F.hasFnAttribute("tvm_raw_func")) { + OutStreamer->EmitRawText("\t.internal\t:" + CurrentFnSym->getName()); + } else { + AsmPrinter::EmitFunctionHeader(); + } +} - const auto &Mapping = lower.getMCInstrsMap(); - const MachineBasicBlock *MBB = nullptr; +void TVMAsmPrinter::EmitFunctionBodyEnd() { + unsigned Blocks = MF->size(); + if (Blocks < 2) + return; - auto I = llvm::find_if(Inst, [](const MCOperand &op) { return op.isInst(); }); - if (I != Inst.end()) { - auto MIit = Mapping.find(I->getInst()); - if (MIit != Mapping.end()) { - if ((MBB = MIit->second->getParent())) - EmitBBEntry(*MBB); + auto *FI = MF->getInfo(); + unsigned Arguments = FI->getParams().size(); + unsigned ReturnValues = FI->getResults().size(); + + if (Arguments > 0) { + if (Blocks <= 16 && Arguments <= 16) { + OutStreamer->EmitRawText(" BLKSWAP\t" + Twine(Arguments) + ", " + + Twine(Blocks)); + } else { + OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Arguments)); + OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Blocks)); + OutStreamer->EmitRawText(" BLKSWX"); } } - for (const auto &op : Inst) { - if (op.isInst()) { - auto &curInst = *op.getInst(); - if (isVerbose()) { - auto MIit = Mapping.find(&curInst); - // PUSHCONT_MBB comment will be printed later, at closing brace '}' - if (MIit != Mapping.end() && curInst.getOpcode() != TVM::PUSHCONT_MBB_S) - for (auto &Comment : MFI->getStackModelComments(MIit->second)) - OutStreamer->AddComment(Comment); - if (curInst.getOpcode() == TVM::FALLTHROUGH_RETURN) { - OutStreamer->AddComment("fallthrough return"); - OutStreamer->AddBlankLine(); - } - } - OutStreamer->GetOS() << "\t"; - static_cast(OutStreamer->GetOS()). - PadToColumn(10 + depth); - EmitToStreamer(*OutStreamer, curInst); - if (curInst.getOpcode() == TVM::PUSHCONT_MBB_S) - EmitSubBlockForPushcont(lower, curInst, depth + 2); + OutStreamer->EmitRawText(" PUSH s" + Twine(Blocks + Arguments - 1)); + OutStreamer->EmitRawText(" EXECUTE"); + + if (ReturnValues > 0) { + if (Blocks <= 16 && ReturnValues <= 16) { + OutStreamer->EmitRawText(" BLKSWAP\t" + Twine(Blocks) + ", " + + Twine(ReturnValues)); + } else { + OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Blocks)); + OutStreamer->EmitRawText(" PUSHINT\t" + Twine(ReturnValues)); + OutStreamer->EmitRawText(" BLKSWX"); } } - if (isVerbose()) { - // Print PUSHCONT_MBB comments at close brace '}' - auto MIit = Mapping.find(&Inst); - if (MIit != Mapping.end()) - for (auto &Comment : MFI->getStackModelComments(MIit->second)) - OutStreamer->AddComment(Comment); - } - OutStreamer->EmitRawText("\t" + std::string(depth, ' ') + "}\n"); -} - -void TVMAsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { - EmitBBEntry(MBB); -} -void TVMAsmPrinter::EmitFunctionHeader() { - const Function &F = MF->getFunction(); - if (F.hasFnAttribute("tvm_raw_func")) { - OutStreamer->EmitRawText("\t.internal\t:" + CurrentFnSym->getName()); + if (Blocks < 16) { + OutStreamer->EmitRawText(" BLKDROP\t" + Twine(Blocks)); } else { - AsmPrinter::EmitFunctionHeader(); + OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Blocks)); + OutStreamer->EmitRawText(" DROPX"); } } diff --git a/llvm/lib/Target/TVM/TVMContinuationsHoist.cpp b/llvm/lib/Target/TVM/TVMContinuationsHoist.cpp deleted file mode 100644 index 883a317bfac7..000000000000 --- a/llvm/lib/Target/TVM/TVMContinuationsHoist.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//===- TVMContinuationsHoist.cpp - hoist PUSHCONTs into common def --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "TVMInstrInfo.h" -#include "TVMRegisterInfo.h" -#include "TVMSubtarget.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Pass.h" - -#define DEBUG_TYPE "tvm-cont-hoist" - -using namespace llvm; - -namespace llvm { - void initializeTVMContinuationsHoistPass(PassRegistry&); - FunctionPass *createTVMContinuationsHoist(); -} - -namespace { - class TVMContinuationsHoist : public MachineFunctionPass { - public: - static char ID; - TVMContinuationsHoist() : MachineFunctionPass(ID) {} - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addPreserved(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - StringRef getPassName() const override { - return "TVM continuations hoisting pass"; - } - bool runOnMachineFunction(MachineFunction &MF) override; - - private: - const TVMInstrInfo *TII = nullptr; - MachineDominatorTree *MDT = nullptr; - MachineRegisterInfo *MRI = nullptr; - - struct OccuranciesInfo { - SmallVector Instructions; - }; - std::map Info; - SmallSet DeleteMIs; - - void collectInstr(MachineInstr &MI); - void collect(MachineFunction &MF); - bool optimize(); - }; -} - -INITIALIZE_PASS_BEGIN(TVMContinuationsHoist, "tvm-cont-hoist", - "TVM continuations hoisting pass", false, false) -INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) -INITIALIZE_PASS_END(TVMContinuationsHoist, "tvm-cont-hoist", - "TVM continuations hoisting pass", false, false) - -char TVMContinuationsHoist::ID = 0; - -void TVMContinuationsHoist::collect(MachineFunction &MF) { - Info.clear(); - DeleteMIs.clear(); - for (MachineBasicBlock &MBB : MF) - for (MachineInstr &MI : MBB) - collectInstr(MI); -} - -bool TVMContinuationsHoist::optimize() { - bool Changed = false; - for (auto *MI : DeleteMIs) { - LLVM_DEBUG(dbgs() << "Erasing unused: " << *MI << "\n"); - MI->eraseFromParent(); - } - for (const auto &Pair : Info) { - auto TargetMBB = Pair.first; - const auto &Instrs = Pair.second.Instructions; - if (Instrs.size() < 2) - continue; - Changed = true; - - auto CommonDom = Instrs.front()->getParent(); - for (auto CurNextMI : drop_begin(Instrs, 1)) { - assert(CommonDom && "PUSHCONT_MBB with null parent"); - assert(CurNextMI->getParent() && "PUSHCONT_MBB with null parent"); - CommonDom = MDT->findNearestCommonDominator(CommonDom, - CurNextMI->getParent()); - } - - MachineInstr *FoundMI = nullptr; - for (MachineInstr &MI : *CommonDom) { - if (MI.getOpcode() == TVM::PUSHCONT_MBB && - MI.getOperand(1).getMBB() == TargetMBB) { - FoundMI = &MI; - break; - } - if (MI.isTerminator()) - break; - } - - unsigned MBBReg = 0; - if (FoundMI) { - MBBReg = FoundMI->getOperand(0).getReg(); - FoundMI->clearRegisterDeads(MBBReg); - } else { - MBBReg = MRI->createVirtualRegister(&TVM::I257RegClass); - BuildMI(*CommonDom, CommonDom->getFirstInstrTerminator(), DebugLoc(), - TII->get(TVM::PUSHCONT_MBB), MBBReg).addMBB(TargetMBB).addImm(0); - } - - for (auto CurDefMI : Instrs) { - if (FoundMI && FoundMI == CurDefMI) - continue; - auto OldDefMO = CurDefMI->getOperand(0); - assert(OldDefMO.isReg() && "PUSHCONT_MBB def is not reg"); - CurDefMI->eraseFromParent(); - - MRI->replaceRegWith(OldDefMO.getReg(), MBBReg); - } - MRI->clearKillFlags(MBBReg); - } - return Changed; -} - -void TVMContinuationsHoist::collectInstr(MachineInstr &MI) { - if (MI.getOpcode() == TVM::PUSHCONT_MBB) { - if (MRI->use_nodbg_empty(MI.getOperand(0).getReg())) { - DeleteMIs.insert(&MI); - return; - } - auto BB = MI.getOperand(1); - assert(BB.isMBB() && "PUSHCONT_MBB operand 1 is not MBB"); - auto MBB = BB.getMBB(); - Info[MBB].Instructions.push_back(&MI); - } -} - -bool TVMContinuationsHoist::runOnMachineFunction(MachineFunction &MF) { - LLVM_DEBUG(MF.print(dbgs() << "Before " << getPassName() << '\n', nullptr)); - - TII = MF.getSubtarget().getInstrInfo(); - MDT = &getAnalysis(); - MRI = &MF.getRegInfo(); - - collect(MF); - bool Changed = optimize(); - - LLVM_DEBUG({ - if (Changed) - MF.print(dbgs() << "After " << getPassName() << '\n', nullptr); - else - dbgs() << "No changes\n"; - }); - return Changed; -} - -FunctionPass *llvm::createTVMContinuationsHoist() { - return new TVMContinuationsHoist(); -} diff --git a/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td b/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td index 5d5feed149a3..5dec2cf64fbd 100644 --- a/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td +++ b/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td @@ -119,15 +119,6 @@ defm CONST_U257 : I<(outs I257:$res), (ins UImm257:$uimm), "PUSHINT\t$res, $uimm", "PUSHINT\t$uimm", 0x82>; } -let isMoveImm = 1, AddedComplexity = 99 in -defm PUSHCONT_MBB : I<(outs I257:$res), (ins bb_op:$bb, i257imm:$fake_op), - (outs), (ins bb_op:$bb), - [(set I257:$res, (BBWrapper bb:$bb, timm:$fake_op))], - "PUSHCONT", "PUSHCONT", 0x8f>; - -defm PUSHCONT_FUNC : NRI<(outs), (ins function_op:$callee), [], - "PUSHCONT\t$callee", 0x8f>; - // There are no labels in TVM, so this functionality is emulated // using ```PUSHINT label; CALL 1``` defm PUSHCONT_LABEL: NRI<(outs), (ins function_op:$callee), [], diff --git a/llvm/lib/Target/TVM/TVMISelLowering.cpp b/llvm/lib/Target/TVM/TVMISelLowering.cpp index 786a500702bf..f0428e893f53 100644 --- a/llvm/lib/Target/TVM/TVMISelLowering.cpp +++ b/llvm/lib/Target/TVM/TVMISelLowering.cpp @@ -43,8 +43,6 @@ using namespace llvm; #define DEBUG_TYPE "tvm-lower" -constexpr int PUSH_C0_FUNCTION_UNIQUE_ID = -2; - //===----------------------------------------------------------------------===// // Command line options for TVM //===----------------------------------------------------------------------===// @@ -248,11 +246,8 @@ TVMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, if (!CallingConvSupported(CallConv)) fail(DL, DAG, "TVM doesn't support non-C calling conventions"); - // Restore C0 for returning to correct continuation - SDValue SetC0 = RestoreC0(Chain, DL, DAG); - // Lower outputs - SmallVector RetOps(1, SetC0); + SmallVector RetOps(1, Chain); RetOps.append(OutVals.begin(), OutVals.end()); Chain = DAG.getNode(TVMISD::RETURN, DL, MVT::Other, RetOps); @@ -309,69 +304,13 @@ SDValue TVMTargetLowering::LowerFormalArguments( FI->addParam(In.VT); } - // Save C0 for returning to correct continuation - return SaveC0(Chain, DL, DAG); -} - -SDValue TVMTargetLowering::SaveC0(SDValue Chain, const SDLoc &DL, - SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - auto *FI = MF.getInfo(); - - // Save c0 for further return lowering - SDValue GetC0Ops[] = { - DAG.getTargetConstant(Intrinsic::tvm_getreg, DL, MVT::i257), - DAG.getConstant(0, DL, MVT::i257)}; - SDValue GetC0 = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::i257, GetC0Ops); - - MachineRegisterInfo &MRI = MF.getRegInfo(); - unsigned C0VirtReg = MRI.createVirtualRegister(&TVM::I257RegClass); - SDValue C0VirtRegNode = DAG.getCopyToReg(Chain, DL, C0VirtReg, GetC0); - - FI->setC0VirtReg(C0VirtReg); - C0VirtRegNode.getNode()->setNodeId(PUSH_C0_FUNCTION_UNIQUE_ID); - // New PushC0 node has just appeared -> invalidate the cache - HasNoPushC0PredecessorCache.clear(); - - return C0VirtRegNode; -} - -bool TVMTargetLowering::hasPushC0Predecessor(SDNode *Node) const { - int NodeId = Node->getNodeId(); - - if (NodeId == PUSH_C0_FUNCTION_UNIQUE_ID) - return true; - - if (HasNoPushC0PredecessorCache.count(NodeId) != 0) - return false; - - for (const SDUse &Use : Node->ops()) { - if (hasPushC0Predecessor(Use.getNode())) - return true; - } - - HasNoPushC0PredecessorCache.insert(NodeId); - return false; -} + SmallVector Params; + SmallVector Results; + ComputeSignatureVTs(MF.getFunction(), DAG.getTarget(), Params, Results); + for (MVT VT : Results) + FI->addResult(VT); -SDValue TVMTargetLowering::RestoreC0(SDValue Chain, const SDLoc &DL, - SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - auto *FI = MF.getInfo(); - - assert(FI->hasC0VirtReg() && "C0 virtual register has not been saved"); - - if (hasPushC0Predecessor(Chain.getNode())) - return Chain; - - unsigned C0VirtReg = FI->getC0VirtReg(); - SDValue GetC0VirtReg = DAG.getCopyFromReg(Chain, DL, C0VirtReg, MVT::i257); - SDValue SetC0Ops[] = { - Chain, DAG.getTargetConstant(Intrinsic::tvm_setreg, DL, MVT::i257), - DAG.getConstant(0, DL, MVT::i257), GetC0VirtReg}; - SDValue SetC0 = DAG.getNode(ISD::INTRINSIC_VOID, DL, MVT::Other, SetC0Ops); - - return SetC0; + return Chain; } EVT TVMTargetLowering::getOptimalMemOpType(uint64_t /*Sz*/, unsigned /*DstAl*/, @@ -602,18 +541,13 @@ SDValue TVMTargetLowering::LowerBR(SDValue Op, SDLoc DL(Op); SDValue Chain = Op.getOperand(0); SDValue Dest = Op.getOperand(1); - SDValue Zero = DAG.getTargetConstant(0, DL, MVT::i257); if (Chain.getOpcode() == ISD::BRCOND) { SDValue PrevChain = Chain->getOperand(0), Cond = Chain->getOperand(1), ThenBr = Chain->getOperand(2), ElseBr = Dest; - ThenBr = DAG.getNode(TVMISD::BBWrapper, DL, MVT::i257, ThenBr, Zero); - ElseBr = DAG.getNode(TVMISD::BBWrapper, DL, MVT::i257, ElseBr, Zero); - return DAG.getNode(TVMISD::IFELSE, DL, MVT::Other, PrevChain, Cond, ThenBr, ElseBr); } - Dest = DAG.getNode(TVMISD::BBWrapper, DL, MVT::i257, Dest, Zero); return DAG.getNode(TVMISD::JUMPX, DL, MVT::Other, Chain, Dest); } @@ -623,8 +557,6 @@ SDValue TVMTargetLowering::LowerBRCOND(SDValue Op, SDValue Chain = Op.getOperand(0); SDValue Cond = Op.getOperand(1); SDValue Dest = Op.getOperand(2); - SDValue Zero = DAG.getTargetConstant(0, DL, MVT::i257); - Dest = DAG.getNode(TVMISD::BBWrapper, DL, MVT::i257, Dest, Zero); return DAG.getNode(TVMISD::IFJMP, DL, MVT::Other, Chain, Dest, Cond); } diff --git a/llvm/lib/Target/TVM/TVMISelLowering.h b/llvm/lib/Target/TVM/TVMISelLowering.h index d70e04e5a466..01c2ac7fb210 100644 --- a/llvm/lib/Target/TVM/TVMISelLowering.h +++ b/llvm/lib/Target/TVM/TVMISelLowering.h @@ -113,13 +113,6 @@ class TVMTargetLowering : public TargetLowering { SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; - - // Save/restore C0 for return lowering - SDValue SaveC0(SDValue Chain, const SDLoc &DL, SelectionDAG& DAG) const; - SDValue RestoreC0(SDValue Chain, const SDLoc &DL, SelectionDAG& DAG) const; - - bool hasPushC0Predecessor(SDNode *Node) const; - mutable std::set HasNoPushC0PredecessorCache; }; } // namespace llvm diff --git a/llvm/lib/Target/TVM/TVMInstrInfo.cpp b/llvm/lib/Target/TVM/TVMInstrInfo.cpp index 1a7272be956a..22fe4d041b5b 100644 --- a/llvm/lib/Target/TVM/TVMInstrInfo.cpp +++ b/llvm/lib/Target/TVM/TVMInstrInfo.cpp @@ -138,36 +138,15 @@ bool TVMInstrInfo::analyzeBranch(MachineBasicBlock &MBB, } if (!I->isTerminator()) return false; - const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); if (I->getOpcode() == TVM::JMPX) { - assert(I->getOperand(0).isReg() && "JMPX operand is not register"); - unsigned ContReg = I->getOperand(0).getReg(); - auto* PushMI = MRI.getVRegDef(ContReg); - if (!PushMI) - return true; - assert(PushMI && PushMI->getOpcode() == TVM::PUSHCONT_MBB && - "JMPX op is not from PUSHCONT_MBB"); - assert(PushMI->getOperand(1).isMBB() && "PUSHCONT_MBB op is not MBB"); - TBB = PushMI->getOperand(1).getMBB(); + TBB = I->getOperand(0).getMBB(); return false; } if (I->getOpcode() == TVM::IFELSE) { Cond.push_back(MachineOperand::CreateImm(0)); Cond.push_back(I->getOperand(0)); - unsigned TrueReg = I->getOperand(1).getReg(); - unsigned FalseReg = I->getOperand(2).getReg(); - auto* TruePushMI = MRI.getVRegDef(TrueReg); - if (!TruePushMI) - return true; - assert(TruePushMI->getOpcode() == TVM::PUSHCONT_MBB && - "IFELSE op is not from PUSHCONT_MBB"); - auto* FalsePushMI = MRI.getVRegDef(FalseReg); - if (!FalsePushMI) - return true; - assert(FalsePushMI->getOpcode() == TVM::PUSHCONT_MBB && - "IFELSE op is not from PUSHCONT_MBB"); - TBB = TruePushMI->getOperand(1).getMBB(); - FBB = FalsePushMI->getOperand(1).getMBB(); + TBB = I->getOperand(1).getMBB(); + FBB = I->getOperand(2).getMBB(); // BranchFolding trying to make single-block back-branch as TBB // We need to make this swap to prevent infinite loop @@ -181,13 +160,7 @@ bool TVMInstrInfo::analyzeBranch(MachineBasicBlock &MBB, if (I->getOpcode() == TVM::IFJMP || I->getOpcode() == TVM::IFNOTJMP) { Cond.push_back(MachineOperand::CreateImm(I->getOpcode() == TVM::IFNOTJMP)); Cond.push_back(I->getOperand(0)); - unsigned TrueReg = I->getOperand(1).getReg(); - auto* TruePushMI = MRI.getVRegDef(TrueReg); - if (!TruePushMI) - return true; - assert(TruePushMI->getOpcode() == TVM::PUSHCONT_MBB && - "IFJMP op is not from PUSHCONT_MBB"); - TBB = TruePushMI->getOperand(1).getMBB(); + TBB = I->getOperand(1).getMBB(); FBB = nullptr; return false; } @@ -254,31 +227,18 @@ unsigned TVMInstrInfo:: const DebugLoc &DL, int *BytesAdded) const { // Shouldn't be a fall through. assert(TBB && "insertBranch must not be told to insert a fallthrough"); - MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); if (TBB && FBB) { assert(Cond.size() == 2 && "Wrong Conds size"); assert(MBB.getFirstTerminator() == MBB.end() && "Block already has terminator"); bool Inverted = Cond[0].getImm(); auto Pred = Cond[1]; - - // TBB and FBB may be in vregs defined by PUSHCONT_MBB with dominated def - // to this place. - // Or may be not. And then we need to insert PUSHCONT_MBBs before IFELSE. - // And better run TVMContinuationsHoist after to optimize PUSHCONTs. - - unsigned TrueReg = MRI.createVirtualRegister(&TVM::I257RegClass); - BuildMI(&MBB, DL, get(TVM::PUSHCONT_MBB), TrueReg).addMBB(TBB) - .addImm(0); - unsigned FalseReg = MRI.createVirtualRegister(&TVM::I257RegClass); - BuildMI(&MBB, DL, get(TVM::PUSHCONT_MBB), FalseReg).addMBB(FBB) - .addImm(0); if (Inverted) - std::swap(TrueReg, FalseReg); + std::swap(TBB, FBB); BuildMI(&MBB, DL, get(TVM::IFELSE)) .add(Pred) - .addReg(TrueReg) - .addReg(FalseReg); + .addMBB(TBB) + .addMBB(FBB); if (BytesAdded) *BytesAdded = 8 * 3; return 3; @@ -293,26 +253,20 @@ unsigned TVMInstrInfo:: IfJmp->getOpcode() == TVM::IFNOTJMP) && "We can only insert uncond branch after cond branch"); auto Cond = IfJmp->getOperand(0); - unsigned TrueReg = IfJmp->getOperand(1).getReg(); + auto BB = IfJmp->getOperand(1).getMBB(); bool Inverted = IfJmp->getOpcode() == TVM::IFNOTJMP; IfJmp->eraseFromParent(); - unsigned FalseReg = MRI.createVirtualRegister(&TVM::I257RegClass); - BuildMI(&MBB, DL, get(TVM::PUSHCONT_MBB), FalseReg).addMBB(TBB) - .addImm(0); if (Inverted) - std::swap(TrueReg, FalseReg); + std::swap(TBB, BB); BuildMI(&MBB, DL, get(TVM::IFELSE)) .add(Cond) - .addReg(TrueReg) - .addReg(FalseReg); + .addMBB(BB) + .addMBB(TBB); if (BytesAdded) *BytesAdded = 8; return 1; } else { - unsigned TrueReg = MRI.createVirtualRegister(&TVM::I257RegClass); - BuildMI(&MBB, DL, get(TVM::PUSHCONT_MBB), TrueReg).addMBB(TBB) - .addImm(0); - BuildMI(&MBB, DL, get(TVM::JMPX)).addReg(TrueReg); + BuildMI(&MBB, DL, get(TVM::JMPX)).addMBB(TBB); if (BytesAdded) *BytesAdded = 8 * 2; return 2; @@ -325,12 +279,9 @@ unsigned TVMInstrInfo:: bool Inverted = Cond[0].getImm(); auto Pred = Cond[1]; - unsigned TrueReg = MRI.createVirtualRegister(&TVM::I257RegClass); - BuildMI(&MBB, DL, get(TVM::PUSHCONT_MBB), TrueReg).addMBB(TBB) - .addImm(0); BuildMI(&MBB, DL, get(Inverted ? TVM::IFNOTJMP : TVM::IFJMP)) .add(Pred) - .addReg(TrueReg); + .addMBB(TBB); if (BytesAdded) *BytesAdded = 8 * 2; return 2; @@ -370,35 +321,10 @@ void enumMBBoperands(MachineInstr &Term, Func func) { void TVMInstrInfo::ReplaceUsesOfBlockWith(MachineBasicBlock *Pred, MachineBasicBlock *Old, MachineBasicBlock *New) const { - MachineRegisterInfo &MRI = Pred->getParent()->getRegInfo(); for (MachineInstr &Term : Pred->terminators()) { enumMBBoperands(Term, [&](MachineOperand &Op) { - if (!Op.isReg()) - return; - unsigned MbbReg = Op.getReg(); - auto* PushMI = MRI.getVRegDef(MbbReg); - if (PushMI->getOpcode() != TVM::PUSHCONT_MBB) - return; - assert(PushMI->getOperand(1).isMBB() && "PUSHCONT_MBB op is not MBB"); - - if (PushMI->getOperand(1).getMBB() == Old) { - if (MRI.hasOneNonDBGUse(MbbReg)) { - // If we have only one non-debug use, we can override existing mbb - PushMI->getOperand(1).setMBB(New); - } else { - // We need to find existing PUSHCONT_MBB with New mbb, - // dominating this terminator, - // Or insert new PUSHCONT_MBB right before terminator - // or before label decl (for back-branches) - - auto it = Pred->getFirstTerminator(); - auto DL = it->getDebugLoc(); - MbbReg = MRI.createVirtualRegister(&TVM::I257RegClass); - BuildMI(*Pred, it, DL, get(TVM::PUSHCONT_MBB), MbbReg).addMBB(New) - .addImm(0); - Op.setReg(MbbReg); - } - } + if (Op.isMBB() && Op.getMBB() == Old) + Op.setMBB(New); }); } // Update the successor information. @@ -407,6 +333,5 @@ void TVMInstrInfo::ReplaceUsesOfBlockWith(MachineBasicBlock *Pred, bool TVMInstrInfo::canFallthrough(MachineBasicBlock &, MachineBasicBlock &To) const { - // We can fallthrough only to block with single predecessor. - return To.pred_size() == 1; + return false; } diff --git a/llvm/lib/Target/TVM/TVMMachineFunctionInfo.h b/llvm/lib/Target/TVM/TVMMachineFunctionInfo.h index 28687729d2b7..dc70c0254976 100644 --- a/llvm/lib/Target/TVM/TVMMachineFunctionInfo.h +++ b/llvm/lib/Target/TVM/TVMMachineFunctionInfo.h @@ -53,9 +53,6 @@ class TVMFunctionInfo final : public MachineFunctionInfo { /// - defined and used in LIFO order with other stack registers BitVector VRegStackified; - /// Virtual register allocated to save c0 for function return lowering - unsigned C0VirtReg = 0; - public: explicit TVMFunctionInfo(MachineFunction &MF); ~TVMFunctionInfo() override; @@ -181,17 +178,6 @@ class TVMFunctionInfo final : public MachineFunctionInfo { assert(Reg & INT32_MIN); return Reg & INT32_MAX; } - - // Accessors to work with virtual register for c0 saving - unsigned int getC0VirtReg() const { return C0VirtReg; } - - bool hasC0VirtReg() const { return C0VirtReg != 0; } - - void setC0VirtReg(unsigned Register) { - assert(!hasC0VirtReg() && "C0 virtual register has been already saved"); - assert(Register && "C0 virtual register has to be non zero"); - C0VirtReg = Register; - } }; void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, diff --git a/llvm/lib/Target/TVM/TVMPeephole.cpp b/llvm/lib/Target/TVM/TVMPeephole.cpp deleted file mode 100644 index 3ed28ffa3f61..000000000000 --- a/llvm/lib/Target/TVM/TVMPeephole.cpp +++ /dev/null @@ -1,486 +0,0 @@ -//===------------ TVMPeephole.cpp - TVM Peephole Optimiztions -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// Late peephole optimizations for TVM. -/// -//===----------------------------------------------------------------------===// - -#include "TVM.h" -#include "TVMMachineFunctionInfo.h" -#include "TVMMachineInstrMatcher.h" -#include "TVMSubtarget.h" -#include "TVMUtilities.h" -#include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" - -using namespace llvm; - -#define DEBUG_TYPE "tvm-peephole" - -static cl::opt - DisableTVMReturnOpt("disable-tvm-return-opt", cl::Hidden, - cl::desc("TVM: Disable return optimizations."), - cl::init(false)); -static cl::opt - DisableTVMIfElseOpt("disable-tvm-ifelse-peephole-opt", cl::Hidden, - cl::desc("TVM: Disable IFELSE peephole optimizations."), - cl::init(false)); - -namespace { -class TVMPeephole final : public MachineFunctionPass { - StringRef getPassName() const override { return "TVM peephole optimizer"; } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - bool runOnMachineFunction(MachineFunction &MF) override; - bool runOnMachineBasicBlock(MachineBasicBlock &MBB, - const TargetInstrInfo &TII); - bool runImplicitReturnOptimization(MachineBasicBlock &MBB, - const TargetInstrInfo &TII); - bool runMbbInlineOptimization(MachineBasicBlock &MBB, - const TargetInstrInfo &TII); - bool runIfElseOptimization(MachineBasicBlock &MBB, - const TargetInstrInfo &TII); - bool runIfElseInlining(MachineBasicBlock::instr_iterator &Iter, - MachineBasicBlock &MBB, const TargetInstrInfo &TII); - bool runIfElseEmptyBranchRemoving(MachineBasicBlock::instr_iterator &Iter, - MachineBasicBlock &MBB, - const TargetInstrInfo &TII); - -public: - static char ID; - TVMPeephole() : MachineFunctionPass(ID) {} -}; -} // end anonymous namespace - -char TVMPeephole::ID = 0; -INITIALIZE_PASS(TVMPeephole, DEBUG_TYPE, "TVM peephole optimizations", false, - false) - -FunctionPass *llvm::createTVMPeephole() { return new TVMPeephole(); } - -static bool MaybeOptimizeReturn(MachineInstr &MI, const TargetInstrInfo &TII) { - MachineBasicBlock *MBB = MI.getParent(); - MachineFunction *MF = MBB->getParent(); - if (DisableTVMReturnOpt) - return false; - - assert(!MBB->empty() && "Empty BBs must already have been removed"); - - if (MBB != &MF->back()) - return false; - - // If we don't need to clean up stack on return, we could omit this - // instruction in the exit BB. - BuildMI(&MI, TII.get(TVM::FALLTHROUGH_RETURN)); - MI.eraseFromParent(); - - return true; -} - -bool TVMPeephole::runImplicitReturnOptimization(MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { - if (MBB.empty()) - return false; - - auto &MI = MBB.back(); - return MI.isReturn() && MaybeOptimizeReturn(MI, TII); -} - -bool TVMPeephole::runMbbInlineOptimization(MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { - if (MBB.empty()) - return false; - - auto InstrIter = MBB.instr_rbegin(); - auto &JmpX = *InstrIter; - - if (JmpX.getOpcode() != TVM::JMPX_S) - return false; - - ++InstrIter; - - auto FirstStackInstrIter = InstrIter; - bool PushContMBBFound = false; - - while (InstrIter != MBB.instr_rend() && !PushContMBBFound) { - switch (InstrIter->getOpcode()) { - case TVM::PUSHCONT_MBB_S: - PushContMBBFound = true; - break; - // Auxilary stack operations should be skipped here and then converted - // below to transform the MI sequence to (PUSHCONT, JMPX) form - case TVM::NIP: - ++InstrIter; - break; - default: - return false; - } - } - - auto LastStackInstrIter = InstrIter; - - if (!PushContMBBFound) - return false; - - auto &PushContMBB = *InstrIter; - - if (PushContMBB.getOpcode() != TVM::PUSHCONT_MBB_S) - return false; - - assert(PushContMBB.getNumOperands() >= 1 && - PushContMBB.getOperand(0).isMBB() && - "MachineBasicBlock should be an operand for PUSHCONT_MBB_S"); - - LLVM_DEBUG( - { dbgs() << " inline JMPX %bb." + Twine(MBB.getNumber()) << "\n"; }); - - const MachineBasicBlock &SourceMBB = *PushContMBB.getOperand(0).getMBB(); - auto InsertionIter = InstrIter.getReverse(); - MachineFunction *MF = MBB.getParent(); - TVMFunctionInfo *MFI = MF->getInfo(); - - // Convert MI sequence to expected form (PUSHCONT, JMPX) and move all - // stack operations between PUSHCONT and JMPX before the PUSHCONT - // (the list of possible transformations may be extended in future) - for (InstrIter = FirstStackInstrIter; InstrIter != LastStackInstrIter;) { - if (InstrIter->getOpcode() == TVM::NIP) { - MFI->clearIntermediateData(BuildMI(&*InsertionIter, TII.get(TVM::DROP))); - } - - auto Next = InstrIter; - ++Next; - InstrIter->eraseFromParent(); - InstrIter = Next; - } - - for (auto &MI : SourceMBB) { - MachineInstr &NewMI = MF->CloneMachineInstrBundle(MBB, InsertionIter, MI); - MFI->cloneMachineInstrIntermediateData(&MI, &NewMI); - } - - PushContMBB.eraseFromParent(); - JmpX.eraseFromParent(); - - return true; -} - -bool TVMPeephole::runIfElseInlining( - MachineBasicBlock::instr_iterator &InstrIter, MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { - MachineInstr *PushContA = nullptr; - MachineInstr *PushContB = nullptr; - MachineInstr *PushContC = nullptr; - MachineInstr *Ifelse = nullptr; - - static constexpr int MaxInstructionsToRemove = 10; - std::array InstrToRemove; - int NumInstrToRemove = 0; - - MachineInstrMatcher Matcher; - bool MatchFound = false; - bool NeedInsertSwapBeforePostDominator = false; - - if (!MatchFound) { - Matcher = MachineInstrMatcher(InstrIter, MBB.instr_end()); - - MachineInstr *Roll = nullptr; - MachineInstr *Blkswap = nullptr; - MachineInstr *Swap = nullptr; - - if (Matcher.match(PushContA, TVM::PUSHCONT_MBB_S) && - Matcher.match(PushContB, TVM::PUSHCONT_MBB_S) && - Matcher.match(PushContC, TVM::PUSHCONT_MBB_S) && - Matcher.match(Roll, TVM::ROLL, 3) && - Matcher.match(Blkswap, TVM::BLKSWAP, 2, 2) && - Matcher.match(Swap, TVM::SWAP) && - Matcher.match(Ifelse, TVM::IFELSE_S)) { - MatchFound = true; - InstrToRemove[NumInstrToRemove++] = Roll; - InstrToRemove[NumInstrToRemove++] = Blkswap; - InstrToRemove[NumInstrToRemove++] = Swap; - } - } - - if (!MatchFound) { - Matcher = MachineInstrMatcher(InstrIter, MBB.instr_end()); - - MachineInstr *Blkswap1 = nullptr; - MachineInstr *Swap1 = nullptr; - MachineInstr *Roll1 = nullptr; - MachineInstr *Roll2 = nullptr; - MachineInstr *Blkswap2 = nullptr; - MachineInstr *Swap2 = nullptr; - - if (Matcher.match(PushContA, TVM::PUSHCONT_MBB_S) && - Matcher.match(PushContB, TVM::PUSHCONT_MBB_S) && - Matcher.match(PushContC, TVM::PUSHCONT_MBB_S) && - Matcher.match(Blkswap1, TVM::BLKSWAP, 2, 4) && - Matcher.match(Swap1, TVM::SWAP) && Matcher.match(Roll1, TVM::ROLL, 2) && - Matcher.match(Roll2, TVM::ROLL, 5) && - Matcher.match(Blkswap2, TVM::BLKSWAP, 2, 4) && - Matcher.match(Swap2, TVM::SWAP) && - Matcher.match(Ifelse, TVM::IFELSE_S)) { - MatchFound = true; - NeedInsertSwapBeforePostDominator = true; - InstrToRemove[NumInstrToRemove++] = Blkswap1; - InstrToRemove[NumInstrToRemove++] = Swap1; - InstrToRemove[NumInstrToRemove++] = Roll1; - InstrToRemove[NumInstrToRemove++] = Roll2; - InstrToRemove[NumInstrToRemove++] = Blkswap2; - InstrToRemove[NumInstrToRemove++] = Swap2; - } - } - - if (!MatchFound) - return false; - - MachineBasicBlock *ContA = PushContA->getOperand(0).getMBB(); - MachineBasicBlock *ContB = PushContB->getOperand(0).getMBB(); - MachineBasicBlock *ContC = PushContC->getOperand(0).getMBB(); - - assert(ContA && ContB && ContC && - "PUSHCONT_MBB_S should have MachineBasicBlock as an operand #0"); - - if (ContA->empty() || ContB->empty()) { - return false; - } - - MachineInstr &ContAJmpX = ContA->instr_back(); - MachineInstr &ContBJmpX = ContB->instr_back(); - - if (ContAJmpX.getOpcode() != TVM::JMPX_S || - ContBJmpX.getOpcode() != TVM::JMPX_S) { - return false; - } - - MachineFunction *MF = MBB.getParent(); - TVMFunctionInfo *MFI = MF->getInfo(); - - // Check if the C branch is the same for THEN & ELSE - const std::vector *ContAJmpXRegs = - MFI->getStackModelSourceRegs(&ContAJmpX); - const std::vector *ContBJmpXRegs = - MFI->getStackModelSourceRegs(&ContBJmpX); - - if (!ContAJmpXRegs || !ContBJmpXRegs || ContAJmpXRegs->empty() || - ContBJmpXRegs->empty()) { - return false; - } - - unsigned AJmpXReg = (*ContAJmpXRegs)[0]; - unsigned BJmpXReg = (*ContBJmpXRegs)[0]; - - if (AJmpXReg != BJmpXReg) { - return false; - } - - LLVM_DEBUG({ - dbgs() << " inline IFELSE post-dominator %bb." + Twine(ContC->getNumber()) - << "\n"; - }); - - auto InsertionIter = Matcher.iter(); - - // NULL instead of post-dominator continuation - DebugLoc DL; - MFI->clearIntermediateData(BuildMI(PushContA, TII.get(TVM::PUSHNULL_S))); - MFI->clearIntermediateData(BuildMI(PushContA, TII.get(TVM::SWAP))); - MFI->clearIntermediateData( - BuildMI(MBB, InsertionIter, DL, TII.get(TVM::DROP))); - - // Insert swap for case #2 - if (NeedInsertSwapBeforePostDominator) { - MFI->clearIntermediateData( - BuildMI(MBB, InsertionIter, DL, TII.get(TVM::SWAP))); - } - - // Copy post-dominator commands after IFELSE - for (auto &MI : *ContC) { - MachineInstr &NewMI = MF->CloneMachineInstrBundle(MBB, InsertionIter, MI); - MFI->cloneMachineInstrIntermediateData(&MI, &NewMI); - } - - MFI->clearIntermediateData( - BuildMI(&ContAJmpX, TII.get(TVM::FALLTHROUGH_RETURN))); - MFI->clearIntermediateData( - BuildMI(&ContBJmpX, TII.get(TVM::FALLTHROUGH_RETURN))); - - // Swap then / else branches - MBB.insert(InstrIter, PushContB->removeFromParent()); - --InstrIter; - - PushContC->eraseFromParent(); - - for (int i = 0; i < NumInstrToRemove; i++) - InstrToRemove[i]->eraseFromParent(); - - ContAJmpX.eraseFromParent(); - ContBJmpX.eraseFromParent(); - - return true; -} - -namespace { - -bool isContinuationEmpty(const MachineBasicBlock &MBB) { - if (MBB.empty()) - return true; - - if (MBB.size() > 1) - return false; - - const MachineInstr &LastInstr = MBB.instr_back(); - - if (LastInstr.getOpcode() == TVM::FALLTHROUGH_RETURN) - return true; - - return false; -} - -} // namespace - -bool TVMPeephole::runIfElseEmptyBranchRemoving( - MachineBasicBlock::instr_iterator &InstrIter, MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { - MachineInstrMatcher Matcher(InstrIter, MBB.instr_end()); - - MachineInstr *PushContA = nullptr; - MachineInstr *PushContB = nullptr; - MachineInstr *Ifelse = nullptr; - - if (!Matcher.match(PushContA, TVM::PUSHCONT_MBB_S) || - !Matcher.match(PushContB, TVM::PUSHCONT_MBB_S) || - !Matcher.match(Ifelse, TVM::IFELSE_S)) { - return false; - } - - MachineFunction *MF = MBB.getParent(); - TVMFunctionInfo *MFI = MF->getInfo(); - - MachineBasicBlock *ContA = PushContA->getOperand(0).getMBB(); - MachineBasicBlock *ContB = PushContB->getOperand(0).getMBB(); - - assert(ContA && ContB && - "PUSHCONT_MBB_S should have MachineBasicBlock as an operand #0"); - - bool ContAEmpty = isContinuationEmpty(*ContA); - bool ContBEmpty = isContinuationEmpty(*ContB); - - if (ContAEmpty && ContBEmpty) { - LLVM_DEBUG({ - dbgs() << " remove IFELSE (%bb." + Twine(ContA->getNumber()) - << ", %bb." + Twine(ContB->getNumber()) << ")\n"; - }); - - InstrIter = Matcher.iter(); // move to the next instruction after IFELSE - - MFI->clearIntermediateData(BuildMI(&*PushContA, TII.get(TVM::DROP))); - - PushContA->eraseFromParent(); - PushContB->eraseFromParent(); - Ifelse->eraseFromParent(); - - return true; - } - - if (ContAEmpty) { - LLVM_DEBUG({ - dbgs() << " remove IFELSE 'then' branch %bb." + Twine(ContA->getNumber()) - << "\n"; - }); - - InstrIter++; // move to 'else' branch - - MFI->clearIntermediateData(BuildMI(&*Ifelse, TII.get(TVM::IFNOT_S))); - - PushContA->eraseFromParent(); - Ifelse->eraseFromParent(); - - return true; - } - - if (ContBEmpty) { - LLVM_DEBUG({ - dbgs() << " remove IFELSE 'else' branch %bb." + Twine(ContB->getNumber()) - << "\n"; - }); - - MFI->clearIntermediateData(BuildMI(&*Ifelse, TII.get(TVM::IF_S))); - - PushContB->eraseFromParent(); - Ifelse->eraseFromParent(); - - return true; - } - - return false; -} - -bool TVMPeephole::runIfElseOptimization(MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { - if (DisableTVMIfElseOpt) - return false; - - auto InstrIter = MBB.instr_begin(); - bool Changed = false; - - for (; InstrIter != MBB.instr_end();) { - if (!runIfElseInlining(InstrIter, MBB, TII) && - !runIfElseEmptyBranchRemoving(InstrIter, MBB, TII)) { - ++InstrIter; - continue; - } - - Changed = true; - } - - return Changed; -} - -bool TVMPeephole::runOnMachineBasicBlock(MachineBasicBlock &MBB, - const TargetInstrInfo &TII) { - bool Changed = false; - - while (runMbbInlineOptimization(MBB, TII)) - Changed |= true; - - Changed |= runImplicitReturnOptimization(MBB, TII); - - return Changed; -} - -bool TVMPeephole::runOnMachineFunction(MachineFunction &MF) { - LLVM_DEBUG({ - dbgs() << "********** Peephole **********\n" - << "********** Function: " << MF.getName() << '\n'; - }); - - const auto *TII = MF.getSubtarget().getInstrInfo(); - - assert(TII && "TargetInstrInfo must be a valid object"); - - bool Changed = false; - - for (auto &MBB : MF) { - Changed |= runOnMachineBasicBlock(MBB, *TII); - } - - for (auto &MBB : MF) { - Changed |= runIfElseOptimization(MBB, *TII); - } - - return Changed; -} diff --git a/llvm/lib/Target/TVM/TVMStackBlockInfo.h b/llvm/lib/Target/TVM/TVMStackBlockInfo.h index 62e4eb962c54..b298b1ea241b 100644 --- a/llvm/lib/Target/TVM/TVMStackBlockInfo.h +++ b/llvm/lib/Target/TVM/TVMStackBlockInfo.h @@ -54,6 +54,13 @@ class TVMStackBlockInfo { void setRoadEnd(unsigned roadEnd) { RoadEnd = roadEnd; } + + unsigned getID() { + return ID; + } + void setID(unsigned id) { + ID = id; + } private: MachineBasicBlock *MBB = nullptr; /// Initial stack state @@ -65,6 +72,8 @@ class TVMStackBlockInfo { unsigned RoadBegin = 0; unsigned RoadEnd = 0; + + unsigned ID; }; } // namespace llvm diff --git a/llvm/lib/Target/TVM/TVMStackModel.cpp b/llvm/lib/Target/TVM/TVMStackModel.cpp index 10cd6818f097..d0f8177676e0 100644 --- a/llvm/lib/Target/TVM/TVMStackModel.cpp +++ b/llvm/lib/Target/TVM/TVMStackModel.cpp @@ -320,8 +320,10 @@ void TVMStackModel::prepareRoads(MachineFunction &MF) { BBInfo.clear(); BBInfo.reserve(MF.size()); + unsigned ID = MF.size(); for (auto &MBB : MF) { BBInfo[&MBB].setMBB(&MBB); + BBInfo[&MBB].setID(--ID); } /// TODO: It's better to encode keep infor about roads with a more expressive @@ -676,6 +678,36 @@ void TVMStackModel::rewriteToSForm(MachineInstr &MI, } } + if (MI.getOpcode() == TVM::IFELSE) { + auto Then = MI.getOperand(1).getMBB(); + unsigned ThenID = TheStack.size() + BBInfo[Then].getID() + 1; + + auto Else = MI.getOperand(2).getMBB(); + unsigned ElseID = TheStack.size() + BBInfo[Else].getID() + 1; + + MachineInstrBuilder MIB; + if (ThenID < 16 && ElseID < 16) { + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH2)).addImm(ThenID).addImm(ElseID); + MFI->addStackModelComment(MIB.getInstr(), Then->getName()); + MFI->addStackModelComment(MIB.getInstr(), Else->getName()); + } else { + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH)).addImm(ThenID); + MFI->addStackModelComment(MIB.getInstr(), Then->getName()); + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH)).addImm(ElseID + 1); + MFI->addStackModelComment(MIB.getInstr(), Else->getName()); + } + } else if (MI.getOpcode() == TVM::JMPX) { + auto Dest = MI.getOperand(0).getMBB(); + unsigned DestID = TheStack.size() + BBInfo[Dest].getID(); + + auto MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH)).addImm(DestID); + MFI->addStackModelComment(MIB.getInstr(), Dest->getName()); + } + MachineInstrBuilder MIB = BuildMI(&MI, TII->get(NewOpcode)); if (NewOpcode != TVM::PUSH_GLOBAL_ADDRESS_S) { @@ -685,20 +717,15 @@ void TVMStackModel::rewriteToSForm(MachineInstr &MI, } } - // Additional immediate is fake op for TVM::PUSHCONT_MBB operation - if (MI.getOpcode() == TVM::PUSHCONT_MBB) { - MIB->addOperand(MI.getOperand(1)); - } else { - for (unsigned I = 0; I < NumImms; I++) { - // Imms are expected to be in continuous sequence - // in register version of MI - const auto &Op = MI.getOperand(NumOperands - NumImms + I); - assert(Op.isImm() || Op.isCImm() && "Expected Imm or CImm"); - if (Op.isImm()) - MIB.addImm(Op.getImm()); - else - MIB.addCImm(Op.getCImm()); - } + for (unsigned I = 0; I < NumImms; I++) { + // Imms are expected to be in continuous sequence + // in register version of MI + const auto &Op = MI.getOperand(NumOperands - NumImms + I); + assert(Op.isImm() || Op.isCImm() && "Expected Imm or CImm"); + if (Op.isImm()) + MIB.addImm(Op.getImm()); + else + MIB.addCImm(Op.getCImm()); } std::vector SourceRegs; diff --git a/llvm/lib/Target/TVM/TVMTargetMachine.cpp b/llvm/lib/Target/TVM/TVMTargetMachine.cpp index 808d1dfb49ca..3081666fdc41 100644 --- a/llvm/lib/Target/TVM/TVMTargetMachine.cpp +++ b/llvm/lib/Target/TVM/TVMTargetMachine.cpp @@ -37,11 +37,9 @@ extern "C" void LLVMInitializeTVMTarget() { initializeTVMRematerializePass(PR); initializeTVMRegStackifyPass(PR); initializeTVMRegNumberingPass(PR); - initializeTVMPeepholePass(PR); initializeTVMStackModelPass(PR); initializeTVMLoopInstructionsPass(PR); initializeTVMLoopPreparePass(PR); - initializeTVMContinuationsHoistPass(PR); initializeTVMLoadStoreReplacePass(PR); } @@ -149,8 +147,6 @@ bool TVMPassConfig::addILPOpts() { void TVMPassConfig::addPreEmitPass() { TargetPassConfig::addPreEmitPass(); - addPass(createTVMContinuationsHoist()); - // Now that we have a prologue and epilogue and all frame indices are // rewritten, eliminate SP and FP. This allows them to be stackified, // colored, and numbered with the rest of the registers. @@ -161,16 +157,11 @@ void TVMPassConfig::addPreEmitPass() { addPass(createTVMLoopInstructions()); addPass(createTVMStackModel()); - // Perform the very last peephole optimizations on the code. - if (getOptLevel() != CodeGenOpt::None) - addPass(createTVMPeephole()); - // Create a mapping from LLVM CodeGen virtual registers to tvm registers. addPass(createTVMRegNumbering()); } void TVMPassConfig::addPreRegAlloc() { - addPass(createTVMContinuationsHoist()); TargetPassConfig::addPreRegAlloc(); } diff --git a/llvm/test/CodeGen/TVM/cfg.ll b/llvm/test/CodeGen/TVM/cfg.ll index 1310ddbfc5cc..f9280ead6b35 100644 --- a/llvm/test/CodeGen/TVM/cfg.ll +++ b/llvm/test/CodeGen/TVM/cfg.ll @@ -5,12 +5,23 @@ target triple = "tvm" ; CHECK-LABEL: brcond define i257 @brcond(i1 %par) nounwind { entry: -; CHECK: PUSHCONT -; CHECK: { -; CHECK: PUSHINT 77 -; CHECK: } -; CHECK: IFNOTJMP -; CHECK: PUSHINT 42 +; CHECK: PUSHCONT { +; CHECK-NEXT: PUSH2 s2, s1 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: PUSHINT 42 +; CHECK-NEXT: RET +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: PUSHINT 77 +; CHECK-NEXT: RET +; CHECK-NEXT: } +; CHECK-NEXT: BLKSWAP 1, 3 +; CHECK-NEXT: PUSH s3 +; CHECK-NEXT: EXECUTE +; CHECK-NEXT: BLKSWAP 3, 1 +; CHECK-NEXT: BLKDROP 3 br i1 %par, label %exit1, label %exit2 exit1: ret i257 42 @@ -25,12 +36,27 @@ declare void @bazz() ; CHECK-LABEL: diamond define void @diamond(i1 %par) nounwind { entry: -; CHECK: PUSHCONT -; CHECK: { -; CHECK: CALL $bar$ -; CHECK: } -; CHECK: IFNOTJMP -; CHECK: CALL $foo$ +; CHECK: PUSHCONT { +; CHECK-NEXT: PUSH2 s3, s2 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: CALL $foo$ +; CHECK-NEXT: PUSH s0 +; CHECK-NEXT: JMPX +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: CALL $bar$ +; CHECK-NEXT: PUSH s0 +; CHECK-NEXT: JMPX +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: RET +; CHECK-NEXT: } +; CHECK-NEXT: BLKSWAP 1, 4 +; CHECK-NEXT: PUSH s4 +; CHECK-NEXT: EXECUTE +; CHECK-NEXT: BLKDROP 4 br i1 %par, label %bb1, label %bb2 bb1: call void @foo() @@ -66,11 +92,29 @@ exit: ; CHECK-LABEL: trivial_phi define i257 @trivial_phi(i1 %par, i257 %val) nounwind { entry: -; CHECK: PUSHCONT -; CHECK: DEC -; CHECK: PUSHCONT -; CHECK: INC -; CHECK: IFNOTJMP +; CHECK: PUSHCONT { +; CHECK-NEXT: SWAP +; CHECK-NEXT: PUSH2 s4, s3 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: INC +; CHECK-NEXT: PUSH s1 +; CHECK-NEXT: JMPX +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: DEC +; CHECK-NEXT: PUSH s1 +; CHECK-NEXT: JMPX +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: RET +; CHECK-NEXT: } +; CHECK-NEXT: BLKSWAP 2, 4 +; CHECK-NEXT: PUSH s5 +; CHECK-NEXT: EXECUTE +; CHECK-NEXT: BLKSWAP 4, 1 +; CHECK-NEXT: BLKDROP 4 br i1 %par, label %bb1, label %bb2 bb1: diff --git a/llvm/test/CodeGen/TVM/hiddenstack.ll b/llvm/test/CodeGen/TVM/hiddenstack.ll index 2861d350615a..ad12080375bd 100644 --- a/llvm/test/CodeGen/TVM/hiddenstack.ll +++ b/llvm/test/CodeGen/TVM/hiddenstack.ll @@ -1,3 +1,4 @@ +; UNSUPPORTED: true ; RUN: llc < %s -march=tvm | FileCheck %s target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257" target triple = "tvm" diff --git a/llvm/test/CodeGen/TVM/load-store-local.ll b/llvm/test/CodeGen/TVM/load-store-local.ll index 63009884a504..346ecf477ba0 100644 --- a/llvm/test/CodeGen/TVM/load-store-local.ll +++ b/llvm/test/CodeGen/TVM/load-store-local.ll @@ -6,7 +6,6 @@ define i257 @test() { ; CHECK: GETGLOB 5 ; CHECK-NEXT: ADDCONST -1 ; CHECK-NEXT: SETGLOB 5 -; CHECK-NEXT: PUSH c0 ; CHECK-NEXT: GETGLOB 5 ; CHECK-NEXT: PUSHINT 18234 ; CHECK-NEXT: GETGLOB 14 CALLX diff --git a/llvm/test/CodeGen/TVM/loops.ll b/llvm/test/CodeGen/TVM/loops.ll index 02fb20bb9aac..6aebf6299a26 100644 --- a/llvm/test/CodeGen/TVM/loops.ll +++ b/llvm/test/CodeGen/TVM/loops.ll @@ -1,15 +1,54 @@ -; RUN: llc < %s -march=tvm | FileCheck %s +; RUN: llc < %s -march=tvm -asm-verbose=0 | FileCheck %s target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257" target triple = "tvm" ; CHECK-LABEL: for_loop +; CHECK: PUSHCONT { +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: PUSH s2 +; CHECK-NEXT: SWAP +; CHECK-NEXT: GREATER +; CHECK-NEXT: ZERO +; CHECK-NEXT: ROLLREV 2 +; CHECK-NEXT: PUSH2 s6, s4 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: ROLL 2 +; CHECK-NEXT: DROP +; CHECK-NEXT: ROLL 2 +; CHECK-NEXT: DROP +; CHECK-NEXT: PUSH s4 +; CHECK-NEXT: JMPX +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: PUSH s1 +; CHECK-NEXT: INC +; CHECK-NEXT: PUSH2 s0, s3 +; CHECK-NEXT: LESS +; CHECK-NEXT: XCHG2 s3, s2 +; CHECK-NEXT: ADD +; CHECK-NEXT: XCHG s0, s2 +; CHECK-NEXT: ROLLREV 2 +; CHECK-NEXT: PUSH2 s5, s4 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: XCHG s0, s2 +; CHECK-NEXT: BLKDROP 2 +; CHECK-NEXT: RET +; CHECK-NEXT: } +; CHECK-NEXT: BLKSWAP 1, 4 +; CHECK-NEXT: PUSH s4 +; CHECK-NEXT: EXECUTE +; CHECK-NEXT: BLKSWAP 4, 1 +; CHECK-NEXT: BLKDROP 4 define i257 @for_loop(i257 %N) nounwind { entry: %cmp6 = icmp sgt i257 %N, 0 - ; CHECK: PUSHCONT - ; CHECK: PUSHCONT - ; CHECK: IFELSE - ; CHECK: JMPX br i1 %cmp6, label %for.body, label %for.cond.cleanup for.cond.cleanup: @@ -26,13 +65,52 @@ for.body: } ; CHECK-LABEL: while_loop +; CHECK: PUSHCONT { +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: PUSH s2 +; CHECK-NEXT: SWAP +; CHECK-NEXT: GREATER +; CHECK-NEXT: ZERO +; CHECK-NEXT: ROLLREV 2 +; CHECK-NEXT: PUSH2 s6, s4 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: PUSHINT 0 +; CHECK-NEXT: ROLL 2 +; CHECK-NEXT: DROP +; CHECK-NEXT: ROLL 2 +; CHECK-NEXT: DROP +; CHECK-NEXT: PUSH s4 +; CHECK-NEXT: JMPX +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: PUSH s1 +; CHECK-NEXT: INC +; CHECK-NEXT: PUSH2 s0, s3 +; CHECK-NEXT: LESS +; CHECK-NEXT: XCHG2 s3, s2 +; CHECK-NEXT: ADD +; CHECK-NEXT: XCHG s0, s2 +; CHECK-NEXT: ROLLREV 2 +; CHECK-NEXT: PUSH2 s5, s4 +; CHECK-NEXT: IFELSE +; CHECK-NEXT: } +; CHECK-NEXT: PUSHCONT { +; CHECK-NEXT: XCHG s0, s2 +; CHECK-NEXT: BLKDROP 2 +; CHECK-NEXT: RET +; CHECK-NEXT: } +; CHECK-NEXT: BLKSWAP 1, 4 +; CHECK-NEXT: PUSH s4 +; CHECK-NEXT: EXECUTE +; CHECK-NEXT: BLKSWAP 4, 1 +; CHECK-NEXT: BLKDROP 4 define i257 @while_loop(i257 %N) nounwind { entry: %cmp5 = icmp sgt i257 %N, 0 - ; CHECK: PUSHCONT - ; CHECK: PUSHCONT - ; CHECK: IFELSE - ; CHECK: JMPX br i1 %cmp5, label %while.body, label %while.end while.body: diff --git a/llvm/test/CodeGen/TVM/optimizations/ifelse.ll b/llvm/test/CodeGen/TVM/optimizations/ifelse.ll deleted file mode 100644 index 18aba1587548..000000000000 --- a/llvm/test/CodeGen/TVM/optimizations/ifelse.ll +++ /dev/null @@ -1,31 +0,0 @@ -; RUN: llc -O3 < %s -march=tvm -filetype=asm | FileCheck %s -target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257" -target triple = "tvm" - -define i257 @double_push(i257 %a, i257 %b) { -entry: - %mul = mul nsw i257 %b, %a - %0 = add i257 %b, %a - %sub = sub i257 %mul, %0 - ret i257 %sub -} - -; CHECK-LABEL: main -define i257 @main() { -; CHECK: EQUAL -; CHECK: PUSHCONT -; CHECK: IFJMP -entry: - %call = tail call i257 @double_push(i257 10, i257 20) - %cmp = icmp eq i257 %call, 170 - br i1 %cmp, label %if.end, label %if.then - -if.then: - tail call void @throw(i257 13) - br label %if.end - -if.end: - ret i257 %call -} - -declare void @throw(i257) diff --git a/llvm/test/CodeGen/TVM/optimizations/pushcont_inline.ll b/llvm/test/CodeGen/TVM/optimizations/pushcont_inline.ll deleted file mode 100644 index 0e0ea017865a..000000000000 --- a/llvm/test/CodeGen/TVM/optimizations/pushcont_inline.ll +++ /dev/null @@ -1,78 +0,0 @@ -; RUN: llc < %s -march=tvm -filetype=asm | FileCheck %s -target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257" -target triple = "tvm" - -; CHECK-LABEL: g -define void @g(i257 %x) { -; CHECK: PUSHCONT -; CHECK: ; {{.*}} -; CHECK-NEXT: { -; CHECK: IFJMP - %x.addr = alloca i257, align 1 - store i257 %x, i257* %x.addr, align 1 - %tobool = icmp ne i257 %x, 0 - br i1 %tobool, label %if.then, label %if.end - -if.then: - br label %return - -if.end: - %x.restored = load i257, i257* %x.addr, align 1 - %call = call i257 @f(i257 %x.restored) - br label %return - -return: - ret void -} - -declare dso_local i257 @f(i257) #1 - -; CHECK-LABEL: k -define dso_local void @k(i257 %x) #0 { -; CHECK: PUSHCONT ; {{.*}} -; CHECK-NEXT: ; {{.*}} -; CHECK-NEXT: { -; CHECK-NEXT: ; %bb.3: ; %if.end -; CHECK: } -; CHECK: PUSHCONT ; {{.*}} -; CHECK-NEXT: ; {{.*}} -; CHECK-NEXT: { -; CHECK-NEXT: ; %bb.2: ; %if.else -; CHECK: } -; CHECK: IFNOTJMP -entry: - %x.addr = alloca i257, align 1 - %y = alloca i257, align 1 - store i257 %x, i257* %x.addr, align 1 - store i257 0, i257* %y, align 1 - %0 = load i257, i257* %x.addr, align 1 - %tobool = icmp ne i257 %0, 0 - br i1 %tobool, label %if.then, label %if.else - -if.then: ; preds = %entry - %1 = load i257, i257* %x.addr, align 1 - %call = call i257 @f1(i257 %1) - %2 = load i257, i257* %x.addr, align 1 - %call1 = call i257 @f1(i257 %2) - %mul = mul nsw i257 %call, %call1 - store i257 %mul, i257* %y, align 1 - br label %if.end - -if.else: ; preds = %entry - %3 = load i257, i257* %x.addr, align 1 - %call2 = call i257 @f2(i257 %3) - %4 = load i257, i257* %x.addr, align 1 - %call3 = call i257 @f2(i257 %4) - %add = add nsw i257 %call2, %call3 - store i257 %add, i257* %y, align 1 - br label %if.end - -if.end: ; preds = %if.else, %if.then - %5 = load i257, i257* %y, align 1 - %call4 = call i257 @f3(i257 %5) - ret void -} - -declare dso_local i257 @f1(i257) #1 -declare dso_local i257 @f2(i257) #1 -declare dso_local i257 @f3(i257) #1 diff --git a/llvm/test/CodeGen/TVM/ret_nested.ll b/llvm/test/CodeGen/TVM/ret_nested.ll deleted file mode 100644 index 5cdbf93974d3..000000000000 --- a/llvm/test/CodeGen/TVM/ret_nested.ll +++ /dev/null @@ -1,90 +0,0 @@ -; RUN: llc -O3 < %s -march=tvm | FileCheck %s -target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257" -target triple = "tvm" - -define i257 @g(i257 %N) nounwind { - ret i257 %N -} - -; CHECK-LABEL: f: -define i257 @f(i257 %N) nounwind { -; CHECK: PUSH c0 -; CHECK: PUSHCONT -; CHECK: PUSHINT 1 -; CHECK: CALL $g$ -; CHECK: SWAP -; CHECK: POP c0 -; CHECK: } -; CHECK: IFNOTJMP - - %status = icmp sgt i257 %N, 0 - br i1 %status, label %then, label %else - -else: - %1 = call i257 @g(i257 1) - ret i257 %1 - -then: - %2 = call i257 @g(i257 2) - ret i257 %2 -} - -; the part below has been added only for runtime testing -define void @test() nounwind { - %1 = call i257 @f(i257 0) - %2 = sub i257 %1, 2 - %flag = trunc i257 %2 to i1 - br i1 %flag, label %do_throw, label %ok -ok: - ret void -do_throw: - call void @llvm.tvm.throw(i257 13) - unreachable -} - -declare void @llvm.tvm.throw(i257 %exception) noreturn - -declare i257 @undefined_f(i257) - -; CHECK-LABEL: l: -define i257 @l(i257 %x) { -; CHECK: PUSH c0 -; CHECK: PUSHCONT -; CHECK: { -; CHECK: POP c0 -; CHECK: } -; CHECK: IFJMP -; CHECK: PUSHCONT -; CHECK: { -; CHECK: POP c0 -; CHECK: } -; CHECK: IFNOTJMP -entry: - %0 = icmp eq i257 %x, 0 - br i1 %0, label %if.else, label %if.then - -if.then: - %1 = tail call i257 @undefined_f(i257 %x) - %2 = icmp ne i257 %1, 0 - br i1 %2, label %if.then2, label %if.else2 - -if.then2: - %3 = tail call i257 @undefined_f(i257 %x) - ret i257 %3 - -if.else2: - ret i257 4 - -if.else: - ret i257 0 -} - -; CHECK-LABEL: k: -define i257 @k(i257 %x) { -entry: -; CHECK-NOT: PUSH c0 -; CHECK: ADDCONST 3 -; CHECK-NOT: POP c0 - %add = add nsw i257 %x, 3 - ret i257 %add -} From 56784126e04a8aade01c94884fb3e0c7b048fc32 Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Fri, 13 Mar 2020 15:48:26 +0300 Subject: [PATCH 2/9] Fix undef-bug.ll phi case --- llvm/lib/Target/TVM/TVMStackFixup.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/TVM/TVMStackFixup.cpp b/llvm/lib/Target/TVM/TVMStackFixup.cpp index 4a71f9a4b57b..1e196215f63b 100644 --- a/llvm/lib/Target/TVM/TVMStackFixup.cpp +++ b/llvm/lib/Target/TVM/TVMStackFixup.cpp @@ -95,7 +95,8 @@ StackFixup StackFixup::Diff(const Stack &to, const Stack &from) { // Generate changes to re-order assert(llvm::size(unmaskedTo) == llvm::size(curStack)); - generateVagonXchgs(rv, curStack, unmaskedTo); + if (llvm::size(curStack) > 0) + generateVagonXchgs(rv, curStack, unmaskedTo); rv.optimize(); return rv; } @@ -225,6 +226,7 @@ void StackFixup::generateVagonXchgs(StackFixup &rv, const Stack &from, auto Tr = Train::build(curStack, to); auto restVagons = llvm::make_range(Tr.Vagons.begin(), Tr.Vagons.end()); + assert(restVagons.begin() != restVagons.end()); auto V = *restVagons.begin(); if (V.DeepIdx + 1 == Sz && !V.Inverted) { restVagons = drop_begin(restVagons, 1); @@ -378,9 +380,12 @@ StackFixup StackFixup::DiffForArgs(const Stack &From, const MIArgs &Args, (ArgInfo[0].Push && Vreg.VirtReg == TVMFunctionInfo::UnusedReg) ? 0 : CurStack.position(Vreg); - if (ArgInfo[0].Push) - rv(CurStack += rv(pushI(Pos))); - else if (Pos != 0) + if (ArgInfo[0].Push) { + if (CurStack.size() > 0) + rv(CurStack += rv(pushI(Pos))); + else + rv(CurStack += rv(pushUndef())); + } else if (Pos != 0) rv(CurStack += rv(xchgTop(Pos))); } else if (Ar.size() == 2 && !HasBigNums) { auto Pos0 = ArgInfo[0].SrcPos; From 9d34abc26f95a247cda4e89571b1e64c6dcd2d27 Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Tue, 17 Mar 2020 15:32:02 +0300 Subject: [PATCH 3/9] Drop hiddenstack intrinsic --- llvm/include/llvm/IR/IntrinsicsTVM.td | 4 --- llvm/lib/Target/TVM/TVMInstrInfo.td | 3 -- llvm/lib/Target/TVM/TVMStack.cpp | 1 - llvm/lib/Target/TVM/TVMStackFixup.cpp | 9 ------ llvm/lib/Target/TVM/TVMStackFixup.h | 13 ++------- llvm/lib/Target/TVM/TVMStackModel.cpp | 9 ------ llvm/test/CodeGen/TVM/hiddenstack.ll | 28 ------------------- .../clang/include/clang/Basic/BuiltinsTVM.def | 1 - stdlib/stdlib_c.tvm | 8 ++++++ stdlib/ton-sdk/smart-contract-info.c | 4 +-- 10 files changed, 12 insertions(+), 68 deletions(-) delete mode 100644 llvm/test/CodeGen/TVM/hiddenstack.ll diff --git a/llvm/include/llvm/IR/IntrinsicsTVM.td b/llvm/include/llvm/IR/IntrinsicsTVM.td index 376685fa5a90..b99fd63398f2 100644 --- a/llvm/include/llvm/IR/IntrinsicsTVM.td +++ b/llvm/include/llvm/IR/IntrinsicsTVM.td @@ -674,8 +674,4 @@ let TargetPrefix = "tvm" in { foreach i = 1-255 in def int_tvm_unpackfirst#i : GCCBuiltin<"__builtin_tvm_unpackfirst"#i>, Intrinsic; - - def int_tvm_hiddenstack : - GCCBuiltin<"__builtin_tvm_hiddenstack">, - Intrinsic<[llvm_i257_ty], [llvm_i257_ty], [IntrNoMem]>; } diff --git a/llvm/lib/Target/TVM/TVMInstrInfo.td b/llvm/lib/Target/TVM/TVMInstrInfo.td index 861738b430a4..6b5c0432396e 100644 --- a/llvm/lib/Target/TVM/TVMInstrInfo.td +++ b/llvm/lib/Target/TVM/TVMInstrInfo.td @@ -237,9 +237,6 @@ defm PU2XC : SI<(ins stack_op:$i, stack_op:$j, stack_op:$k), defm PUSH3 : SI<(ins stack_op:$i, stack_op:$j, stack_op:$k), "PUSH3\t$i, $j, $k", 0x547>; -let isPseudo=1 in -def HIDDENSTACK : NI<(outs I257:$dst), (ins uimm8:$src), [(set I257:$dst, (int_tvm_hiddenstack uimm8:$src))], 1>; - defm POP : SI<(ins stack_op:$dst), "POP\t$dst", 0x30>; defm DROP : SI<(ins), "DROP", 0x30>; defm BLKDROP : SI<(ins uimm8:$sz), "BLKDROP\t$sz", 0x5F0>; diff --git a/llvm/lib/Target/TVM/TVMStack.cpp b/llvm/lib/Target/TVM/TVMStack.cpp index 50197dc6d0b2..beba0ac29fb4 100644 --- a/llvm/lib/Target/TVM/TVMStack.cpp +++ b/llvm/lib/Target/TVM/TVMStack.cpp @@ -154,7 +154,6 @@ Stack& Stack::operator += (const StackFixup::Change &change) { std::swap(Data[v.i], Data[v.j]); }, [this](StackFixup::pushI v){ Data.push_front(Data[v.i]); }, - [ ](StackFixup::pushHidden v){ }, [this](StackFixup::pushUndef){ Data.push_front(StackVreg(TVMFunctionInfo::UnusedReg)); }, diff --git a/llvm/lib/Target/TVM/TVMStackFixup.cpp b/llvm/lib/Target/TVM/TVMStackFixup.cpp index 1e196215f63b..70c24e84160f 100644 --- a/llvm/lib/Target/TVM/TVMStackFixup.cpp +++ b/llvm/lib/Target/TVM/TVMStackFixup.cpp @@ -458,14 +458,6 @@ StackFixup StackFixup::DiffForArgs(const Stack &From, const MIArgs &Args, return rv; } -StackFixup StackFixup::DiffForHiddenStack(const Stack &Src, size_t Element, - unsigned OutRegister) { - Stack CurrentStack(Src); - StackFixup rv; - rv(CurrentStack += rv(pushHidden(Src.size() + Element, OutRegister))); - return rv; -} - void StackFixup::apply(Stack &stack) const { for (auto p : Changes) stack += p.first; @@ -600,7 +592,6 @@ void StackFixup::printElem(raw_ostream &OS, const Change &change) const { [&](xchgTop v) { OS << "xchg s(" << v.i << ")"; }, [&](xchg v) { OS << "xchg s(" << v.i << "), s(" << v.j << ")"; }, [&](pushI v) { OS << "push s(" << v.i << ")"; }, - [&](pushHidden v) { OS << "push s(" << v.i << ")"; }, [&](pushUndef) { OS << "zero"; }, [&](blkswap v) { OS << "blkswap " << v.deepSz << ", " << v.topSz; }, [&](roll v) { diff --git a/llvm/lib/Target/TVM/TVMStackFixup.h b/llvm/lib/Target/TVM/TVMStackFixup.h index ad9a18ca5933..f15fc78a19b0 100644 --- a/llvm/lib/Target/TVM/TVMStackFixup.h +++ b/llvm/lib/Target/TVM/TVMStackFixup.h @@ -63,9 +63,6 @@ class StackFixup { static StackFixup DiffForArgs(const Stack &Src, const MIArgs &Args, bool IsCommutative = false); - static StackFixup DiffForHiddenStack(const Stack &Src, size_t Element, - unsigned OutRegister); - void apply(Stack &stack) const; // Remove one copy of this elem @@ -109,12 +106,6 @@ class StackFixup { } unsigned i; }; - struct pushHidden : pushI { - explicit pushHidden(unsigned i, unsigned reg, bool checkLimits = true) - : pushI(i, checkLimits), reg(reg) {} - unsigned i; - unsigned reg; - }; struct dup : pushI { dup() : pushI(0) {} }; @@ -251,8 +242,8 @@ class StackFixup { : tripleChange(true, true, false, i, j, k) {} }; using Change = - std::variant; + std::variant; using ChangesVec = std::vector>; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) diff --git a/llvm/lib/Target/TVM/TVMStackModel.cpp b/llvm/lib/Target/TVM/TVMStackModel.cpp index d0f8177676e0..823225d7f647 100644 --- a/llvm/lib/Target/TVM/TVMStackModel.cpp +++ b/llvm/lib/Target/TVM/TVMStackModel.cpp @@ -525,15 +525,6 @@ StackFixup TVMStackModel::prepareStackFor(MachineInstr &MI, if (MI.isImplicitDef()) return {}; - if (MI.getOpcode() == TVM::HIDDENSTACK) { - auto Result = MI.getOperand(0); - auto Operand = MI.getOperand(1); - assert(Result.isReg() && Operand.isCImm() && "Unexpected instruction format"); - return StackFixup::DiffForHiddenStack(StackBefore, - Operand.getCImm()->getZExtValue(), - Result.getReg()); - } - auto *MBB = MI.getParent(); #ifndef NDEBUG diff --git a/llvm/test/CodeGen/TVM/hiddenstack.ll b/llvm/test/CodeGen/TVM/hiddenstack.ll deleted file mode 100644 index ad12080375bd..000000000000 --- a/llvm/test/CodeGen/TVM/hiddenstack.ll +++ /dev/null @@ -1,28 +0,0 @@ -; UNSUPPORTED: true -; RUN: llc < %s -march=tvm | FileCheck %s -target datalayout = "E-S257-i1:257:257-i8:257:257-i16:257:257-i32:257:257-i64:257:257-i257:257:257-p:257:257-a:257:257" -target triple = "tvm" - -declare i257 @llvm.tvm.hiddenstack(i257 %index) - -; CHECK-LABEL: hstack: -define i257 @hstack() nounwind { -; CHECK: PUSH s1 - %1 = call i257 @llvm.tvm.hiddenstack(i257 1) - ret i257 %1 -} - -; CHECK-LABEL: hstack_args: -define i257 @hstack_args(i257 %a, i257 %b, i257 %c) nounwind { -; CHECK: { %{{[0-9]+}} | %{{[0-9]+}} | %{{[0-9]+}} | - } -; CHECK: PUSH s10 -; CHECK: { %{{[0-9]+}} | %{{[0-9]+}} | %{{[0-9]+}} | %{{[0-9]+}} | - } - %1 = call i257 @llvm.tvm.hiddenstack(i257 7) -; CHECK: ADD -; CHECK: ADD -; CHECK: ADD - %2 = add i257 %1, %a - %3 = add i257 %2, %b - %4 = add i257 %3, %c - ret i257 %4 -} diff --git a/llvm/tools/clang/include/clang/Basic/BuiltinsTVM.def b/llvm/tools/clang/include/clang/Basic/BuiltinsTVM.def index 683b90bc7834..051283b9d291 100644 --- a/llvm/tools/clang/include/clang/Basic/BuiltinsTVM.def +++ b/llvm/tools/clang/include/clang/Basic/BuiltinsTVM.def @@ -703,6 +703,5 @@ BUILTIN(__builtin_tvm_unpackfirst252, "T252Tt", "nc") BUILTIN(__builtin_tvm_unpackfirst253, "T253Tt", "nc") BUILTIN(__builtin_tvm_unpackfirst254, "T254Tt", "nc") BUILTIN(__builtin_tvm_unpackfirst255, "T255Tt", "nc") -BUILTIN(__builtin_tvm_hiddenstack, "WiWi", "nc") #undef BUILTIN diff --git a/stdlib/stdlib_c.tvm b/stdlib/stdlib_c.tvm index 18442882c0da..c36b3a81cf63 100644 --- a/stdlib/stdlib_c.tvm +++ b/stdlib/stdlib_c.tvm @@ -88,6 +88,10 @@ tvm_sender_pubkey: PUSH s1 SETGLOB 7 + PUSH s2 + SETGLOB 8 + PUSH s3 + SETGLOB 9 PUSHCONT { CALL $load_macro$ @@ -135,6 +139,10 @@ tvm_sender_pubkey: PUSH s1 SETGLOB 7 + PUSH s2 + SETGLOB 8 + PUSH s3 + SETGLOB 9 PUSHCONT { CALL $load_macro$ diff --git a/stdlib/ton-sdk/smart-contract-info.c b/stdlib/ton-sdk/smart-contract-info.c index 09e9450721fb..d8ae263492b5 100644 --- a/stdlib/ton-sdk/smart-contract-info.c +++ b/stdlib/ton-sdk/smart-contract-info.c @@ -9,9 +9,9 @@ SmartContractInfo get_SmartContractInfo () { #include "smart-contract-info.inc" unsigned contract_balance() { - return __builtin_tvm_hiddenstack(4); + return __builtin_tvm_getglobal(9); } unsigned message_balance() { - return __builtin_tvm_hiddenstack(3); + return __builtin_tvm_getglobal(8); } From 08d59015203e2996d39448342ad2a7d5ce7790ef Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Tue, 17 Mar 2020 22:49:20 +0300 Subject: [PATCH 4/9] Improve asm formatting --- llvm/lib/Target/TVM/TVMAsmPrinter.cpp | 1 + llvm/lib/Target/TVM/TVMCellInstrInfo.td | 22 +++++++++++----------- llvm/lib/Target/TVM/TVMInstrFormats.td | 2 +- llvm/test/CodeGen/TVM/load-store-global.ll | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp index d15e48e535da..69e06985fc78 100644 --- a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp +++ b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp @@ -116,6 +116,7 @@ void TVMAsmPrinter::EmitInstruction(const MachineInstr *MI) { case TVM::FROM_SLICE_COPY_S: case TVM::FROM_BUILDER_COPY_S: case TVM::FROM_CELL_COPY_S: + case TVM::PUSH_GLOBAL_ADDRESS_S: break; case TVM::FALLTHROUGH_RETURN: if (isVerbose()) { diff --git a/llvm/lib/Target/TVM/TVMCellInstrInfo.td b/llvm/lib/Target/TVM/TVMCellInstrInfo.td index e4c5150f9ab4..9d0261ace8d5 100644 --- a/llvm/lib/Target/TVM/TVMCellInstrInfo.td +++ b/llvm/lib/Target/TVM/TVMCellInstrInfo.td @@ -79,16 +79,16 @@ defm LDI : I<(outs I257 : $x, Slice : $sliceo), (outs), (ins uimm1_256 : $precision), [(set I257 : $x, Slice : $sliceo, (int_tvm_ldi Slice : $slicei, uimm1_256 : $precision))], - "LDI\t $precision, $slicei, $x, $sliceo", - "LDI\t $precision", 0xd2>; + "LDI\t$precision, $slicei, $x, $sliceo", + "LDI\t$precision", 0xd2>; defm LDU : I<(outs I257 : $x, Slice : $sliceo), (ins Slice : $slicei, uimm1_256 : $precision), (outs), (ins uimm1_256 : $precision), [(set I257 : $x, Slice : $sliceo, (int_tvm_ldu Slice : $slicei, uimm1_256 : $precision))], - "LDU\t $precision, $slicei, $x, $sliceo", - "LDU\t $precision", 0xd3>; + "LDU\t$precision, $slicei, $x, $sliceo", + "LDU\t$precision", 0xd3>; defm LDIX : I0<(outs I257 : $x, Slice : $sliceo), (ins Slice : $slicei, I257 : $precision), @@ -107,8 +107,8 @@ defm LDUQ : I<(outs I257:$x, Slice:$sliceo, I257:$succ), (outs), (ins uimm1_256:$precision), [(set I257:$x, Slice:$sliceo, I257:$succ, (int_tvm_lduq Slice:$slicei, uimm1_256:$precision))], - "LDUQ\t $precision, $slicei, $x, $sliceo, $succ", - "LDUQ\t $precision NULLROTRIFNOT", 0xd70d>; + "LDUQ\t$precision, $slicei, $x, $sliceo, $succ", + "LDUQ\t$precision NULLROTRIFNOT", 0xd70d>; defm LDUXQ : I0<(outs I257:$x, Slice:$sliceo, I257:$succ), (ins Slice:$slicei, I257:$precision), @@ -162,16 +162,16 @@ defm PLDI : I<(outs I257:$x), (outs), (ins uimm1_256:$precision), [(set I257:$x, (int_tvm_pldi Slice:$slicei, uimm1_256:$precision))], - "PLDI\t $precision, $slicei, $x", - "PLDI\t $precision", 0xd70a00>; + "PLDI\t$precision, $slicei, $x", + "PLDI\t$precision", 0xd70a00>; defm PLDU : I<(outs I257:$x), (ins Slice:$slicei, uimm1_256:$precision), (outs), (ins uimm1_256:$precision), [(set I257:$x, (int_tvm_pldu Slice:$slicei, uimm1_256:$precision))], - "PLDU\t $precision, $slicei, $x", - "PLDU\t $precision", 0xd70b00>; + "PLDU\t$precision, $slicei, $x", + "PLDU\t$precision", 0xd70b00>; defm PLDIX : I0<(outs I257:$x), (ins Slice:$slicei, I257:$precision), [(set I257:$x, (int_tvm_pldu Slice:$slicei, I257:$precision))], @@ -194,7 +194,7 @@ defm STUXR : I0<(outs Builder : $builder), defm LDREFRTOS : I<(outs Slice:$cellslice, Slice:$sliceo), (ins Slice:$slicei), (outs), (ins), [(set Slice:$cellslice, Slice:$sliceo, (int_tvm_ldrefrtos Slice:$slicei))], - "LDREFRTOS\t $cellslice, $sliceo, $slicei", "LDREFRTOS", 0xd5>; + "LDREFRTOS\t$cellslice, $sliceo, $slicei", "LDREFRTOS", 0xd5>; let hasSideEffects = 1 in defm LDREF : I<(outs Cell:$ocell, Slice:$oslice), (ins Slice:$islice), diff --git a/llvm/lib/Target/TVM/TVMInstrFormats.td b/llvm/lib/Target/TVM/TVMInstrFormats.td index ebb19dec4242..d5648fbb6e7c 100644 --- a/llvm/lib/Target/TVM/TVMInstrFormats.td +++ b/llvm/lib/Target/TVM/TVMInstrFormats.td @@ -18,7 +18,7 @@ class TVMInst inst, string asmstr, bit stack> : Instruction { field bit StackBased = stack; let Namespace = "TVM"; let Pattern = []; - let AsmString = asmstr; + let AsmString = !subst("\t", " ", asmstr); } // Normal instructions. Default instantiation of a TVMInst. diff --git a/llvm/test/CodeGen/TVM/load-store-global.ll b/llvm/test/CodeGen/TVM/load-store-global.ll index 6ffd7bcd01f1..1c8899e7383f 100644 --- a/llvm/test/CodeGen/TVM/load-store-global.ll +++ b/llvm/test/CodeGen/TVM/load-store-global.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=tvm | FileCheck %s +; RUN: llc < %s -march=tvm -asm-verbose=0 | FileCheck %s target triple = "tvm" @value1 = global i257 1 From bd9790e199a52a75a48c8db01d1ae9338f64239d Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Wed, 18 Mar 2020 23:24:21 +0300 Subject: [PATCH 5/9] Drop PUSH_GLOBAL_ADDRESS, PUSHCONT_LABEL --- .../Target/TVM/InstPrinter/TVMInstPrinter.cpp | 21 ---------- llvm/lib/Target/TVM/TVMAsmPrinter.cpp | 1 - .../lib/Target/TVM/TVMControlFlowInstrInfo.td | 13 +----- llvm/lib/Target/TVM/TVMRematerialize.cpp | 2 - llvm/lib/Target/TVM/TVMStackModel.cpp | 40 ++----------------- 5 files changed, 5 insertions(+), 72 deletions(-) diff --git a/llvm/lib/Target/TVM/InstPrinter/TVMInstPrinter.cpp b/llvm/lib/Target/TVM/InstPrinter/TVMInstPrinter.cpp index aa9b9f30532d..f28c55f4fdc8 100644 --- a/llvm/lib/Target/TVM/InstPrinter/TVMInstPrinter.cpp +++ b/llvm/lib/Target/TVM/InstPrinter/TVMInstPrinter.cpp @@ -32,25 +32,6 @@ using namespace llvm; void TVMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) { - // TODO: A hack, we have the same logic in AsmPrinter, but it's not triggered - // for instructions in TVM::PUSHCONT_MBB. Need to find a better solution. - switch (MI->getOpcode()) { - case TVM::TO_TUPLE_COPY_S: - case TVM::TO_SLICE_COPY_S: - case TVM::TO_BUILDER_COPY_S: - case TVM::TO_CELL_COPY_S: - case TVM::FROM_TUPLE_COPY_S: - case TVM::FROM_SLICE_COPY_S: - case TVM::FROM_BUILDER_COPY_S: - case TVM::FROM_CELL_COPY_S: - case TVM::REG_TO_REG_COPY_S: - case TVM::PUSH_GLOBAL_ADDRESS_S: - case TVM::FALLTHROUGH_RETURN: - return; - default: - break; - } - { std::string Str; raw_string_ostream OStr(Str); @@ -80,8 +61,6 @@ void TVMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, if (const auto *Expr = dyn_cast(Op.getExpr())) { O << Expr->getString(); } else { - assert((Info.OperandType == TVM::OPERAND_FUNCTION) && - "Unimplemented expression type"); // The actual label address is not known at the moment of // code generation; to simplify further linking, the label name // is surrounded with dollar signs ($callee$). diff --git a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp index 69e06985fc78..d15e48e535da 100644 --- a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp +++ b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp @@ -116,7 +116,6 @@ void TVMAsmPrinter::EmitInstruction(const MachineInstr *MI) { case TVM::FROM_SLICE_COPY_S: case TVM::FROM_BUILDER_COPY_S: case TVM::FROM_CELL_COPY_S: - case TVM::PUSH_GLOBAL_ADDRESS_S: break; case TVM::FALLTHROUGH_RETURN: if (isVerbose()) { diff --git a/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td b/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td index 5dec2cf64fbd..a19ead77779e 100644 --- a/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td +++ b/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td @@ -119,11 +119,6 @@ defm CONST_U257 : I<(outs I257:$res), (ins UImm257:$uimm), "PUSHINT\t$res, $uimm", "PUSHINT\t$uimm", 0x82>; } -// There are no labels in TVM, so this functionality is emulated -// using ```PUSHINT label; CALL 1``` -defm PUSHCONT_LABEL: NRI<(outs), (ins function_op:$callee), [], - "PUSHINT\t$callee", 0x82>; - defm PUSHC : I<(outs I257 : $root), (ins uimm8 : $regno), (outs), (ins uimm8 : $regno), [(set I257 : $root, (int_tvm_getreg uimm8 : $regno))], @@ -211,11 +206,7 @@ def : Pat<(store Cell : $value, I257 : $addr), def : Pat<(truncstore I257 : $value, I257 : $addr), (CALL_STORE_INT I257 : $addr, I257 : $value)>; -defm PUSH_GLOBAL_ADDRESS : I<(outs I257 : $res), (ins I257 : $in), - (outs), (ins I257 : $in), - [], "PUSHINT\t$res, $in", "PUSHINT\t$in", 0x82>; - def : Pat<(i257 (TVMGlobalAddressWrapper tglobaladdr : $addr)), - (PUSH_GLOBAL_ADDRESS tglobaladdr : $addr)>; + (CONST_I257 tglobaladdr : $addr)>; def : Pat<(i257 (TVMGlobalAddressWrapper texternalsym : $addr)), - (PUSH_GLOBAL_ADDRESS texternalsym : $addr)>; + (CONST_I257 texternalsym : $addr)>; diff --git a/llvm/lib/Target/TVM/TVMRematerialize.cpp b/llvm/lib/Target/TVM/TVMRematerialize.cpp index dc9f8963f943..4c50f09fff43 100644 --- a/llvm/lib/Target/TVM/TVMRematerialize.cpp +++ b/llvm/lib/Target/TVM/TVMRematerialize.cpp @@ -62,8 +62,6 @@ FunctionPass *llvm::createTVMRematerialize() { return new TVMRematerialize(); } // Test whether Def is safe and profitable to rematerialize. static bool ShouldRematerialize(const MachineInstr &Def, AliasAnalysis &AA, const TVMInstrInfo *TII) { - if (Def.getOpcode() == TVM::PUSH_GLOBAL_ADDRESS) - return true; return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def, &AA); } diff --git a/llvm/lib/Target/TVM/TVMStackModel.cpp b/llvm/lib/Target/TVM/TVMStackModel.cpp index 823225d7f647..c9c2e29a9784 100644 --- a/llvm/lib/Target/TVM/TVMStackModel.cpp +++ b/llvm/lib/Target/TVM/TVMStackModel.cpp @@ -637,38 +637,6 @@ void TVMStackModel::rewriteToSForm(MachineInstr &MI, }); if (NewOpcode >= 0) { - // Global operands and external symbols are represented using GlobalAddress - // and ExternalSymbol DAG nodes. Because of convention of instruction - // operands ordering global addresses and external symbols must be placed - // first before instruction. To avoid custom logic of stack reordering for - // global/external operands, we transfrom all GlobalAddress and - // ExternalSymbol nodes to the chain of PUSH_GLOBAL_ADDRESS(_S) instruction - // and TargetGlobalAddress / TargetExternalSymbol nodes. So by default only - // PUSH_GLOBAL_ADDRESS instruction may have global/external operand. This - // instruction has definition with address which can be normally processed - // using stack model for all further uses of the address result. - // There are may be exceptions when the transformation to - // PUSH_GLOBAL_ADDRESS is not needed (for example, for instructions with - // immediate string operands like LOGSTR). For such cases operands will be - // passed up to lowering to MCInst where they can be customly processed. - - // add global addresses before the command - // TODO: continuation must be modelled in the stack then. - for (unsigned I = 0; I < NumGlobals; I++) { - const auto &Op = MI.getOperand(NumDefs + I); - assert((Op.isGlobal() || Op.isSymbol()) && - "Expected GlobalAddress/ExternalSymbol"); - if (NewOpcode == TVM::PUSH_GLOBAL_ADDRESS_S) { - if (Op.isGlobal()) { - BuildMI(&MI, TII->get(TVM::PUSHCONT_LABEL)) - .addGlobalAddress(Op.getGlobal(), Op.getOffset()); - } else { - BuildMI(&MI, TII->get(TVM::PUSHCONT_LABEL)) - .addExternalSymbol(Op.getSymbolName(), Op.getOffset()); - } - } - } - if (MI.getOpcode() == TVM::IFELSE) { auto Then = MI.getOperand(1).getMBB(); unsigned ThenID = TheStack.size() + BBInfo[Then].getID() + 1; @@ -701,11 +669,9 @@ void TVMStackModel::rewriteToSForm(MachineInstr &MI, MachineInstrBuilder MIB = BuildMI(&MI, TII->get(NewOpcode)); - if (NewOpcode != TVM::PUSH_GLOBAL_ADDRESS_S) { - for (unsigned I = 0; I < NumGlobals; I++) { - const auto &Op = MI.getOperand(NumDefs + I); - MIB->addOperand(Op); - } + for (unsigned I = 0; I < NumGlobals; I++) { + const auto &Op = MI.getOperand(NumDefs + I); + MIB->addOperand(Op); } for (unsigned I = 0; I < NumImms; I++) { From d5e4cf8de34d3a13d437bd1a386f86b9d587ebc3 Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Fri, 20 Mar 2020 00:14:18 +0300 Subject: [PATCH 6/9] Optimize function return --- llvm/lib/Target/TVM/TVMAsmPrinter.cpp | 4 ++-- llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td | 8 ++------ llvm/test/CodeGen/TVM/cfg.ll | 4 ---- llvm/test/CodeGen/TVM/loops.ll | 2 -- llvm/tools/tvm-build/tvm-build++.py | 2 ++ llvm/tools/tvm-build/tvm-build.py | 2 ++ 6 files changed, 8 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp index d15e48e535da..066e2988c708 100644 --- a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp +++ b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp @@ -117,9 +117,9 @@ void TVMAsmPrinter::EmitInstruction(const MachineInstr *MI) { case TVM::FROM_BUILDER_COPY_S: case TVM::FROM_CELL_COPY_S: break; - case TVM::FALLTHROUGH_RETURN: + case TVM::RETURN_N_S: if (isVerbose()) { - OutStreamer->AddComment("fallthrough return"); + OutStreamer->AddComment("implicit return"); OutStreamer->AddBlankLine(); } break; diff --git a/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td b/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td index a19ead77779e..d4c6a53a8bed 100644 --- a/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td +++ b/llvm/lib/Target/TVM/TVMControlFlowInstrInfo.td @@ -19,12 +19,8 @@ //===----------------------------------------------------------------------===// let isTerminator = 1, hasCtrlDep = 1 in { - let isReturn = 1, isBarrier = 1 in { - defm RETURN_N : NRI<(outs), (ins variable_ops), [(TVMreturn)], - "RET", 0xdb30>; - let isCodeGenOnly = 1 in - defm FALLTHROUGH_RETURN : SI<(ins)>; - } // isReturn = 1, isBarrier = 1 + let isReturn = 1, isBarrier = 1 in + defm RETURN_N : NRI<(outs), (ins variable_ops), [(TVMreturn)]>; let isBranch = 1 in { // The condition operand is a boolean value which TVM represents as i257. diff --git a/llvm/test/CodeGen/TVM/cfg.ll b/llvm/test/CodeGen/TVM/cfg.ll index f9280ead6b35..2d8651d7c218 100644 --- a/llvm/test/CodeGen/TVM/cfg.ll +++ b/llvm/test/CodeGen/TVM/cfg.ll @@ -11,11 +11,9 @@ entry: ; CHECK-NEXT: } ; CHECK-NEXT: PUSHCONT { ; CHECK-NEXT: PUSHINT 42 -; CHECK-NEXT: RET ; CHECK-NEXT: } ; CHECK-NEXT: PUSHCONT { ; CHECK-NEXT: PUSHINT 77 -; CHECK-NEXT: RET ; CHECK-NEXT: } ; CHECK-NEXT: BLKSWAP 1, 3 ; CHECK-NEXT: PUSH s3 @@ -51,7 +49,6 @@ entry: ; CHECK-NEXT: JMPX ; CHECK-NEXT: } ; CHECK-NEXT: PUSHCONT { -; CHECK-NEXT: RET ; CHECK-NEXT: } ; CHECK-NEXT: BLKSWAP 1, 4 ; CHECK-NEXT: PUSH s4 @@ -108,7 +105,6 @@ entry: ; CHECK-NEXT: JMPX ; CHECK-NEXT: } ; CHECK-NEXT: PUSHCONT { -; CHECK-NEXT: RET ; CHECK-NEXT: } ; CHECK-NEXT: BLKSWAP 2, 4 ; CHECK-NEXT: PUSH s5 diff --git a/llvm/test/CodeGen/TVM/loops.ll b/llvm/test/CodeGen/TVM/loops.ll index 6aebf6299a26..4f2f4641c608 100644 --- a/llvm/test/CodeGen/TVM/loops.ll +++ b/llvm/test/CodeGen/TVM/loops.ll @@ -39,7 +39,6 @@ target triple = "tvm" ; CHECK-NEXT: PUSHCONT { ; CHECK-NEXT: XCHG s0, s2 ; CHECK-NEXT: BLKDROP 2 -; CHECK-NEXT: RET ; CHECK-NEXT: } ; CHECK-NEXT: BLKSWAP 1, 4 ; CHECK-NEXT: PUSH s4 @@ -101,7 +100,6 @@ for.body: ; CHECK-NEXT: PUSHCONT { ; CHECK-NEXT: XCHG s0, s2 ; CHECK-NEXT: BLKDROP 2 -; CHECK-NEXT: RET ; CHECK-NEXT: } ; CHECK-NEXT: BLKSWAP 1, 4 ; CHECK-NEXT: PUSH s4 diff --git a/llvm/tools/tvm-build/tvm-build++.py b/llvm/tools/tvm-build/tvm-build++.py index ffcee0dbde4d..783a9f52a4fe 100755 --- a/llvm/tools/tvm-build/tvm-build++.py +++ b/llvm/tools/tvm-build/tvm-build++.py @@ -143,6 +143,8 @@ def get_path(opt, optname, varname, default): else: opt_flags = ['-O3'] +opt_flags += ['-simplifycfg-dup-ret=1'] + _, bitcode_opt = tempfile.mkstemp() execute([os.path.join(tvm_llvm_bin, 'opt')] + opt_flags + [bitcode_int, '-o', bitcode_opt], args.verbose) diff --git a/llvm/tools/tvm-build/tvm-build.py b/llvm/tools/tvm-build/tvm-build.py index 69db28184fc5..ad92b65c2028 100755 --- a/llvm/tools/tvm-build/tvm-build.py +++ b/llvm/tools/tvm-build/tvm-build.py @@ -152,6 +152,8 @@ def get_path(opt, optname, varname, default): else: opt_flags = ['-O3'] +opt_flags += ['-simplifycfg-dup-ret=1'] + _, bitcode_opt = tempfile.mkstemp() execute([os.path.join(tvm_llvm_bin, 'opt')] + opt_flags + [bitcode_int, '-o', bitcode_opt], args.verbose) From 3876755982582c3d3f055449fd896247e21b2f5f Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Mon, 23 Mar 2020 22:52:04 +0300 Subject: [PATCH 7/9] Improve conditional throwing --- llvm/lib/Target/TVM/TVMIfConversionTerm.cpp | 63 +++++++++++++++++++-- llvm/test/CodeGen/TVM/intrinsic.ll | 30 ++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/TVM/TVMIfConversionTerm.cpp b/llvm/lib/Target/TVM/TVMIfConversionTerm.cpp index e30191af37e2..cb6150267f1e 100644 --- a/llvm/lib/Target/TVM/TVMIfConversionTerm.cpp +++ b/llvm/lib/Target/TVM/TVMIfConversionTerm.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "TVM.h" +#include "TVMUtilities.h" + #include "llvm/ADT/PostOrderIterator.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -49,7 +51,8 @@ class TVMIfConversionTerm final : public MachineFunctionPass { static char ID; explicit TVMIfConversionTerm() : MachineFunctionPass(ID) {} private: - bool tryConvertIf(MachineBasicBlock*); + bool tryConvertIf1(MachineBasicBlock *MBB); + bool tryConvertIf2(MachineBasicBlock *MBB); void updateDomTree(MachineBasicBlock *Head, MachineBasicBlock *ThrowBB, MachineBasicBlock *ContBB); @@ -96,7 +99,7 @@ void TVMIfConversionTerm::updateLoops(MachineBasicBlock *ThrowBB, Loops->removeBlock(ContBB); } -bool TVMIfConversionTerm::tryConvertIf(MachineBasicBlock* MBB) { +bool TVMIfConversionTerm::tryConvertIf1(MachineBasicBlock *MBB) { SmallVector RemovedBlocks; MachineBasicBlock *Head = MBB; @@ -148,6 +151,55 @@ bool TVMIfConversionTerm::tryConvertIf(MachineBasicBlock* MBB) { return true; } +static bool IsThrow(MachineBasicBlock *MBB) { + if (!MBB->succ_empty()) + return false; + if (MBB->size() != 1) + return false; + auto &MI = MBB->front(); + if (MI.getOpcode() != TVM::THROW) + return false; + return true; +} + +// ... +// | +// MBB ... +// ... / \ / +// \ / \ / +// \ / \ / +// TBB \ / +// FBB +// | +// ... +bool TVMIfConversionTerm::tryConvertIf2(MachineBasicBlock *MBB) { + MachineBasicBlock *TBB = nullptr; + MachineBasicBlock *FBB = nullptr; + SmallVector Cond; + if (TII->analyzeBranch(*MBB, TBB, FBB, Cond)) + return false; + + unsigned Opcode; + if (TBB && IsThrow(TBB)) { + Opcode = TVM::THROWIF; + } else if (FBB && IsThrow(FBB)) { + std::swap(TBB, FBB); + Opcode = TVM::THROWIFNOT; + } else { + return false; + } + + auto &TI = TBB->front(); + auto &MI = *MBB->getFirstTerminator(); + BuildMI(*MBB, MI, MI.getDebugLoc(), TII->get(Opcode)) + .add(Cond[1]).add(TI.getOperand(0)); + TII->removeBranch(*MBB); + MBB->removeSuccessor(TBB); + TII->insertBranch(*MBB, FBB, nullptr, ArrayRef(), DebugLoc()); + + return true; +} + bool TVMIfConversionTerm::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "********** TVM IF-CONVERSION TERM **********\n" << "********** Function: " << MF.getName() << '\n'); @@ -157,9 +209,12 @@ bool TVMIfConversionTerm::runOnMachineFunction(MachineFunction &MF) { DomTree = &getAnalysis(); Loops = getAnalysisIfAvailable(); bool Changed = false; - for (auto DomNode : post_order(DomTree)) - if (tryConvertIf(DomNode->getBlock())) + for (auto DomNode : post_order(DomTree)) { + if (tryConvertIf1(DomNode->getBlock())) Changed = true; + if (tryConvertIf2(DomNode->getBlock())) + Changed = true; + } return Changed; } diff --git a/llvm/test/CodeGen/TVM/intrinsic.ll b/llvm/test/CodeGen/TVM/intrinsic.ll index bbb0d7f9da20..e6dfb76e76b1 100644 --- a/llvm/test/CodeGen/TVM/intrinsic.ll +++ b/llvm/test/CodeGen/TVM/intrinsic.ll @@ -209,6 +209,21 @@ do_throw: unreachable } +; CHECK-LABEL: throws2 +define void @throws2(i257 %cond1, i257 %cond2) { + %flag1 = trunc i257 %cond1 to i1 + br i1 %flag1, label %bb, label %ok +bb: +; CHECK: THROWIF 42 + %flag2 = trunc i257 %cond2 to i1 + br i1 %flag2, label %do_throw, label %ok +ok: + ret void +do_throw: + call void @llvm.tvm.throw(i257 42) + unreachable +} + ; CHECK-LABEL: throws_neg define void @throws_neg(i257 %cond) { ; CHECK: THROWIFNOT 42 @@ -221,6 +236,21 @@ do_throw: unreachable } +; CHECK-LABEL: throws2_neg +define void @throws2_neg(i257 %cond1, i257 %cond2) { + %flag1 = trunc i257 %cond1 to i1 + br i1 %flag1, label %bb, label %ok +bb: +; CHECK: THROWIFNOT 42 + %flag2 = trunc i257 %cond2 to i1 + br i1 %flag2, label %ok, label %do_throw +ok: + ret void +do_throw: + call void @llvm.tvm.throw(i257 42) + unreachable +} + ; CHECK-LABEL: throws_uncond define void @throws_uncond() { ; CHECK: THROW 42 From c7feb0d7efffa98804973dd67c14afa342be4d20 Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Mon, 30 Mar 2020 16:09:03 +0300 Subject: [PATCH 8/9] Minor improvement --- llvm/lib/Target/TVM/TVMAsmPrinter.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp index 066e2988c708..0cc8c54fdeba 100644 --- a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp +++ b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp @@ -163,14 +163,15 @@ void TVMAsmPrinter::EmitFunctionBodyEnd() { auto *FI = MF->getInfo(); unsigned Arguments = FI->getParams().size(); unsigned ReturnValues = FI->getResults().size(); + const unsigned SmallEncodingLimit = 16; if (Arguments > 0) { - if (Blocks <= 16 && Arguments <= 16) { - OutStreamer->EmitRawText(" BLKSWAP\t" + Twine(Arguments) + ", " + + if (Blocks <= SmallEncodingLimit && Arguments <= SmallEncodingLimit) { + OutStreamer->EmitRawText(" BLKSWAP " + Twine(Arguments) + ", " + Twine(Blocks)); } else { - OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Arguments)); - OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Blocks)); + OutStreamer->EmitRawText(" PUSHINT " + Twine(Arguments)); + OutStreamer->EmitRawText(" PUSHINT " + Twine(Blocks)); OutStreamer->EmitRawText(" BLKSWX"); } } @@ -179,20 +180,20 @@ void TVMAsmPrinter::EmitFunctionBodyEnd() { OutStreamer->EmitRawText(" EXECUTE"); if (ReturnValues > 0) { - if (Blocks <= 16 && ReturnValues <= 16) { - OutStreamer->EmitRawText(" BLKSWAP\t" + Twine(Blocks) + ", " + + if (Blocks <= SmallEncodingLimit && ReturnValues <= SmallEncodingLimit) { + OutStreamer->EmitRawText(" BLKSWAP " + Twine(Blocks) + ", " + Twine(ReturnValues)); } else { - OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Blocks)); - OutStreamer->EmitRawText(" PUSHINT\t" + Twine(ReturnValues)); + OutStreamer->EmitRawText(" PUSHINT " + Twine(Blocks)); + OutStreamer->EmitRawText(" PUSHINT " + Twine(ReturnValues)); OutStreamer->EmitRawText(" BLKSWX"); } } - if (Blocks < 16) { - OutStreamer->EmitRawText(" BLKDROP\t" + Twine(Blocks)); + if (Blocks < SmallEncodingLimit) { + OutStreamer->EmitRawText(" BLKDROP " + Twine(Blocks)); } else { - OutStreamer->EmitRawText(" PUSHINT\t" + Twine(Blocks)); + OutStreamer->EmitRawText(" PUSHINT " + Twine(Blocks)); OutStreamer->EmitRawText(" DROPX"); } } From 78931e2d17d76ec0b23af9bce69b4209a266649a Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Tue, 31 Mar 2020 13:19:56 +0300 Subject: [PATCH 9/9] Support a large number of BBs --- llvm/lib/Target/TVM/TVMAsmPrinter.cpp | 8 ++++++- llvm/lib/Target/TVM/TVMInstrInfo.td | 1 + llvm/lib/Target/TVM/TVMStackModel.cpp | 34 ++++++++++++++++++++++----- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp index 0cc8c54fdeba..1f452e4ffd8f 100644 --- a/llvm/lib/Target/TVM/TVMAsmPrinter.cpp +++ b/llvm/lib/Target/TVM/TVMAsmPrinter.cpp @@ -176,7 +176,13 @@ void TVMAsmPrinter::EmitFunctionBodyEnd() { } } - OutStreamer->EmitRawText(" PUSH s" + Twine(Blocks + Arguments - 1)); + unsigned Entry = Blocks + Arguments - 1; + if (Entry < 256) { + OutStreamer->EmitRawText(" PUSH s" + Twine(Entry)); + } else { + OutStreamer->EmitRawText(" PUSHINT " + Twine(Entry)); + OutStreamer->EmitRawText(" PUSHX"); + } OutStreamer->EmitRawText(" EXECUTE"); if (ReturnValues > 0) { diff --git a/llvm/lib/Target/TVM/TVMInstrInfo.td b/llvm/lib/Target/TVM/TVMInstrInfo.td index 6b5c0432396e..edafe52c3aa1 100644 --- a/llvm/lib/Target/TVM/TVMInstrInfo.td +++ b/llvm/lib/Target/TVM/TVMInstrInfo.td @@ -198,6 +198,7 @@ defm NOP : I<(outs), (ins), (outs), (ins), [(int_tvm_nop)], "NOP", "NOP", 0x00>; let mayLoad = 1, isAsCheapAsAMove = 1 in { defm PUSH : SI<(ins stack_op:$local), "PUSH\t$local", 0x20>; +defm PUSHX : SI<(ins), "PUSHX", 0x60>; defm SWAP : SI<(ins), "SWAP", 0x01>; defm XCHG_TOP : SI<(ins stack_op:$src), "XCHG\ts0, $src", 0x01>; defm XCHG_TOP_DEEP : SI<(ins stack_op:$src), "XCHG\ts0, $src", 0x11>; diff --git a/llvm/lib/Target/TVM/TVMStackModel.cpp b/llvm/lib/Target/TVM/TVMStackModel.cpp index c9c2e29a9784..2b012b519abd 100644 --- a/llvm/lib/Target/TVM/TVMStackModel.cpp +++ b/llvm/lib/Target/TVM/TVMStackModel.cpp @@ -651,19 +651,41 @@ void TVMStackModel::rewriteToSForm(MachineInstr &MI, MFI->addStackModelComment(MIB.getInstr(), Then->getName()); MFI->addStackModelComment(MIB.getInstr(), Else->getName()); } else { - MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), - TII->get(TVM::PUSH)).addImm(ThenID); + if (ThenID < 256) { + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH)).addImm(ThenID); + } else { + BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::CONST_I257_S)).addImm(ThenID); + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSHX)); + } MFI->addStackModelComment(MIB.getInstr(), Then->getName()); - MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), - TII->get(TVM::PUSH)).addImm(ElseID + 1); + if (ElseID < 255) { + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH)).addImm(ElseID + 1); + } else { + BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::CONST_I257_S)).addImm(ElseID + 1); + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSHX)); + } MFI->addStackModelComment(MIB.getInstr(), Else->getName()); } } else if (MI.getOpcode() == TVM::JMPX) { auto Dest = MI.getOperand(0).getMBB(); unsigned DestID = TheStack.size() + BBInfo[Dest].getID(); - auto MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), - TII->get(TVM::PUSH)).addImm(DestID); + MachineInstrBuilder MIB; + if (DestID < 256) { + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSH)).addImm(DestID); + } else { + BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::CONST_I257_S)).addImm(DestID); + MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), + TII->get(TVM::PUSHX)); + } MFI->addStackModelComment(MIB.getInstr(), Dest->getName()); }