From b590c19cc970fb3ce5babf8a72d27bbcb77b13df Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 21 Jun 2025 10:05:06 +0800 Subject: [PATCH 1/4] Revert "[XVM] Add comments on XVM bug fixes" This reverts commit 2e5384e10f7ce56c88977a3638a7cb25d270cdd4. Signed-off-by: Eric --- clang/lib/CodeGen/TargetInfo.cpp | 4 ---- llvm-build/build.py | 2 -- 2 files changed, 6 deletions(-) diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 3b8bf76575b6..619a33956760 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5538,10 +5538,6 @@ public: B.addAttribute("xvm-export-name", Attr->getExportName()); Fn->addFnAttrs(B); } else { - // If the function is static and has a body, we add the always_inline - // attribute to it, unless it has a noinline attribute. - // This is to ensure that the function is inlined when possible. - // This is a common pattern in XVM to optimize performance. if (FD->hasBody() && FD->isStatic()) { const auto *NoInlineAttrVar = FD->getAttr(); llvm::Function *Fn = cast(GV); diff --git a/llvm-build/build.py b/llvm-build/build.py index 55dccecf4764..0984791283e8 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -817,8 +817,6 @@ class LlvmCore(BuildUtils): # First of all build compiler-rt because it's needed to be built before libunwind and etc. if not self.build_config.build_only and not 'windows-x86_64' in build_dir: - # Whether to build compiler-rt before other targets - # due to XVM do not need compiler-rt if need_compiler_rt: self.invoke_ninja(out_path=build_dir, env=env, -- Gitee From bb83f9896cc15d44a2010d14cbb0cda4104d9c0b Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 21 Jun 2025 10:05:38 +0800 Subject: [PATCH 2/4] Revert "[XVM] Remove extra optimization passes" This reverts commit 53400469835d14140f292c214d401e2a26ba9d52. Signed-off-by: Eric --- llvm/lib/Target/XVM/XVMTargetMachine.cpp | 110 +++++++++++------------ 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/llvm/lib/Target/XVM/XVMTargetMachine.cpp b/llvm/lib/Target/XVM/XVMTargetMachine.cpp index eb05f7cc25aa..40aaec7808e6 100644 --- a/llvm/lib/Target/XVM/XVMTargetMachine.cpp +++ b/llvm/lib/Target/XVM/XVMTargetMachine.cpp @@ -48,34 +48,34 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTarget() { initializeDSELegacyPassPass(PR); initializeJumpThreadingPass(PR); - // initializeMachineCSEPass(PR); - // initializeCorrelatedValuePropagationPass(PR); - // initializeInstructionCombiningPassPass(PR); - // initializeSimpleLoopUnswitchLegacyPassPass(PR); - // initializeAggressiveInstCombinerLegacyPassPass(PR); - - // initializeCallSiteSplittingLegacyPassPass(PR); - // initializeFunctionSpecializationLegacyPassPass(PR); - - - // initializeConstantMergeLegacyPassPass(PR); - // initializeGlobalDCELegacyPassPass(PR); - // initializeEliminateAvailableExternallyLegacyPassPass(PR); - // initializeGVNLegacyPassPass(PR); - - // initializeLoopUnrollAndJamPass(PR); - // initializeLoopUnrollPass(PR); - - // // initializeLoopFuseLegacyPass(PR); - // initializeLoopDataPrefetchLegacyPassPass(PR); - // initializeLoopDeletionLegacyPassPass(PR); - // initializeLoopAccessLegacyAnalysisPass(PR); - // initializeLoopInstSimplifyLegacyPassPass(PR); - // initializeLoopInterchangeLegacyPassPass(PR); - // initializeLoopFlattenLegacyPassPass(PR); - // initializeLoopPredicationLegacyPassPass(PR); - // initializeLoopRotateLegacyPassPass(PR); - // initializeLoopStrengthReducePass(PR); + initializeMachineCSEPass(PR); + initializeCorrelatedValuePropagationPass(PR); + initializeInstructionCombiningPassPass(PR); + initializeSimpleLoopUnswitchLegacyPassPass(PR); + initializeAggressiveInstCombinerLegacyPassPass(PR); + + initializeCallSiteSplittingLegacyPassPass(PR); + initializeFunctionSpecializationLegacyPassPass(PR); + + + initializeConstantMergeLegacyPassPass(PR); + initializeGlobalDCELegacyPassPass(PR); + initializeEliminateAvailableExternallyLegacyPassPass(PR); + initializeGVNLegacyPassPass(PR); + + initializeLoopUnrollAndJamPass(PR); + initializeLoopUnrollPass(PR); + + // initializeLoopFuseLegacyPass(PR); + initializeLoopDataPrefetchLegacyPassPass(PR); + initializeLoopDeletionLegacyPassPass(PR); + initializeLoopAccessLegacyAnalysisPass(PR); + initializeLoopInstSimplifyLegacyPassPass(PR); + initializeLoopInterchangeLegacyPassPass(PR); + initializeLoopFlattenLegacyPassPass(PR); + initializeLoopPredicationLegacyPassPass(PR); + initializeLoopRotateLegacyPassPass(PR); + initializeLoopStrengthReducePass(PR); // initializeBasicBlockSectionsPass(PR); } @@ -140,33 +140,33 @@ bool XVMPassConfig::addPreISel() { addPass(createSpeculativeExecutionPass()); addPass(createMergedLoadStoreMotionPass()); - // addPass(createEarlyCSEPass()); - // addPass(createCorrelatedValuePropagationPass()); - // addPass(createInstructionCombiningPass()); - // addPass(createSimpleLoopUnswitchLegacyPass(true)); - // addPass(createAggressiveInstCombinerPass()); - // addPass(createCallSiteSplittingPass()); - // addPass(createFunctionSpecializationPass()); - - // addPass(createConstantMergePass()); - // addPass(createGlobalDCEPass()); - // addPass(createEliminateAvailableExternallyPass()); - // addPass(createTailCallEliminationPass()); - // addPass(createGVNPass(false)); - - // addPass(createLoopUnrollAndJamPass(3)); - // addPass(createLoopUnrollPass(3)); - - // // addPass(createLoopFusePass()); - // addPass(createLoopDataPrefetchPass()); - // addPass(createLoopDeletionPass()); - // // addPass(createLoopAccessLegacyAnalysisPass()); - // addPass(createLoopInstSimplifyPass()); - // addPass(createLoopInterchangePass()); - // addPass(createLoopFlattenPass()); - // addPass(createLoopPredicationPass()); - // addPass(createLoopRotatePass()); - // addPass(createLoopStrengthReducePass()); + addPass(createEarlyCSEPass()); + addPass(createCorrelatedValuePropagationPass()); + addPass(createInstructionCombiningPass()); + addPass(createSimpleLoopUnswitchLegacyPass(true)); + addPass(createAggressiveInstCombinerPass()); + addPass(createCallSiteSplittingPass()); + addPass(createFunctionSpecializationPass()); + + addPass(createConstantMergePass()); + addPass(createGlobalDCEPass()); + addPass(createEliminateAvailableExternallyPass()); + addPass(createTailCallEliminationPass()); + addPass(createGVNPass(false)); + + addPass(createLoopUnrollAndJamPass(3)); + addPass(createLoopUnrollPass(3)); + + // addPass(createLoopFusePass()); + addPass(createLoopDataPrefetchPass()); + addPass(createLoopDeletionPass()); + // addPass(createLoopAccessLegacyAnalysisPass()); + addPass(createLoopInstSimplifyPass()); + addPass(createLoopInterchangePass()); + addPass(createLoopFlattenPass()); + addPass(createLoopPredicationPass()); + addPass(createLoopRotatePass()); + addPass(createLoopStrengthReducePass()); return false; } -- Gitee From 84c66ae3dc5984d219581aa92ea54f91db43b708 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 21 Jun 2025 10:06:15 +0800 Subject: [PATCH 3/4] Revert "[XVM] Bug Fixes" This reverts commit b062cbe0e5aecf6e69343b721539d6c051374518. Signed-off-by: Eric --- clang/lib/CodeGen/TargetInfo.cpp | 9 +- .../Target/XVM/MCTargetDesc/XVMInstPrinter.h | 4 +- llvm/lib/Target/XVM/XVMCFGStackify.cpp | 264 ++++++++---------- llvm/lib/Target/XVM/XVMISelLowering.cpp | 2 +- llvm/lib/Target/XVM/XVMInstrInfo.td | 4 +- llvm/lib/Target/XVM/XVMRegisterInfo.cpp | 18 +- llvm/lib/Target/XVM/XVMTargetMachine.cpp | 66 ----- .../lib/Target/XVM/XVMUpdateRefInstrForMI.cpp | 221 ++------------- 8 files changed, 158 insertions(+), 430 deletions(-) diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 619a33956760..53b623819d8b 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5538,14 +5538,9 @@ public: B.addAttribute("xvm-export-name", Attr->getExportName()); Fn->addFnAttrs(B); } else { - if (FD->hasBody() && FD->isStatic()) { - const auto *NoInlineAttrVar = FD->getAttr(); + if (FD->isStatic()) { llvm::Function *Fn = cast(GV); - if (!NoInlineAttrVar) { - Fn->addFnAttr(llvm::Attribute::AlwaysInline); - } else { - Fn->addFnAttr(llvm::Attribute::NoInline); - } + Fn->addFnAttr(llvm::Attribute::AlwaysInline); } } } diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h index d28cb862843a..abd335ba511b 100644 --- a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h @@ -25,9 +25,9 @@ public: void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override; void printOperand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream, - const char *Mod = nullptr); + const char *Mod = nullptr); void printMemOperand(const MCInst *MInst, int OpNum, raw_ostream &OStream, - const char *Mod = nullptr); + const char *Mod = nullptr); void printImm64Operand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream); void printBrTargetOperand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream); diff --git a/llvm/lib/Target/XVM/XVMCFGStackify.cpp b/llvm/lib/Target/XVM/XVMCFGStackify.cpp index f6c8ec17b176..ad5d438fd01b 100644 --- a/llvm/lib/Target/XVM/XVMCFGStackify.cpp +++ b/llvm/lib/Target/XVM/XVMCFGStackify.cpp @@ -23,7 +23,6 @@ #ifdef XVM_DYLIB_MODE #include "XVM.h" -#include "XVM_def.h" #include "XVMSortRegion.h" #include "XVMSubtarget.h" #include "llvm/ADT/Statistic.h" @@ -73,13 +72,13 @@ class XVMCFGStackify final : public MachineFunctionPass { void insertWithBreak(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); void insertRetBlock(MachineFunction &MF); void removeInFunctionRet(MachineFunction &MF); - void fillEndLoopMap(MachineFunction &MF); // Wrap-up using EndMarkerInfo = std::pair; - unsigned getBranchDepth(MachineFunction &MF, - const MachineBasicBlock *MBB, MachineInstr *MI); + unsigned getBranchDepth(const SmallVectorImpl &Stack, + const std::set *SetEndBlockLoop, + const MachineBasicBlock *MBB); void rewriteDepthImmediates(MachineFunction &MF); void fixBackEdgesOfLoops(MachineFunction &MF); void fixEndsAtEndOfFunction(MachineFunction &MFunction); @@ -121,6 +120,7 @@ class XVMCFGStackify final : public MachineFunctionPass { void registerScope(MachineInstr *Start, MachineInstr *Finish); void registerTryScope(MachineInstr *Start, MachineInstr *Finish, MachineBasicBlock *EHPad); + void unregisterScope(MachineInstr *Start); public: static char ID; // typeid replacement, for identification @@ -139,11 +139,6 @@ FunctionPass *llvm::createXVMCFGStackify() { return new XVMCFGStackify(); } -// Map for EndLoops to MBB number -// Used for calculating Break Immediates -static std::map EndLoopToMBBnum; -// Map for mapping machine instruction to current header of loop if "continue" is used -static std::map ContinueMap; // As opposed to falling through, test whether Pre has any terminators // explicitly branching to MBB. Note: We check to see if therey are any explicit @@ -232,14 +227,6 @@ void ChangeBranchCondOpc(MachineInstr &MI, const XVMInstrInfo *TII) { } } -static inline MachineBasicBlock *getNextBlock(MachineBasicBlock &MBB) { - MachineFunction::iterator I = MBB.getIterator(); - MachineFunction::iterator E = MBB.getParent()->end(); - if (++I == E) - return nullptr; - return &*I; -} - void XVMCFGStackify::fixBackEdgesOfLoops(MachineFunction &MF) { TII = MF.getSubtarget().getInstrInfo(); auto &MLI = getAnalysis(); @@ -254,60 +241,58 @@ void XVMCFGStackify::fixBackEdgesOfLoops(MachineFunction &MF) { if (MI.getNumOperands() <=0) { continue; } - if (TII->isUnCondBranch(&MI) && MI.getOperand(MO_FIRST).getMBB() == LoopHeader) { + if (TII->isUnCondBranch(&MI) && MI.getOperand(0).getMBB() == LoopHeader) { if (&MBB != Loop->getBottomBlock()) { BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(XVM::CONTINUE)); - MI.eraseFromParent(); } + MI.eraseFromParent(); break; - } else if (TII->isCondBranch(&MI) && MI.getOperand(MO_FIRST).getMBB() == LoopHeader) { + } else if (TII->isCondBranch(&MI) && MI.getOperand(0).getMBB() == LoopHeader) { uint32_t action_opcode = XVM::CONTINUE; - int BreakImmValue = getBranchDepth(MF, MI.getOperand(MO_FIRST).getMBB(), &MI); /* Fix Loop Exiting Fallthrough */ - if (BreakImmValue > -1 && ContinueMap[&MI] != MI.getOperand(0).getMBB()->getNumber()) { - action_opcode = XVM::BREAK_IMM; + if (&MBB == Loop->getBottomBlock() && + &MI == &*(--MBB.end()) && + MLI.getLoopFor(MBB.getFallThrough()) != Loop) { + TII->negateCondBranch(&MI); + action_opcode = XVM::BREAK; } - // Check if we need to add a break statement at the end of loop int LevelBreakAfterLoop = -1; - - // 1. if the last stmt of the BB is a conditional branch statement and - // 2. if the next BB is one of its successor and - // 3. if the first statements of the next BB are END_BLOCK/END_LOOP - // insert a break if the above conditions are true - MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(); - MachineInstr &MITmp = *MBBI; - if (MITmp.isTerminator() && TII->isCondBranch(&MITmp)) { - MachineBasicBlock *NextBB = MBB.getNextNode(); - bool NextBBIsSucc = false; - for (auto *Succ : MBB.successors()) { - if (Succ == NextBB) { - NextBBIsSucc = true; - break; + if (action_opcode == XVM::CONTINUE) { + // 1. if the last stmt of the BB is a conditional branch statement and + // 2. if the next BB is one of its successor and + // 3. if the first statements of the next BB are END_BLOCK/END_LOOP + // insert a break if the above conditions are true + MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(); + MachineInstr &MITmp = *MBBI; + if (MITmp.isTerminator() && TII->isCondBranch(&MITmp)) { + MachineBasicBlock *NextBB = MBB.getNextNode(); + bool NextBBIsSucc = false; + for (auto *Succ : MBB.successors()) { + if (Succ == NextBB) { + NextBBIsSucc = true; + break; + } } - } - if (NextBBIsSucc) { - MachineBasicBlock::const_iterator MBBINext = NextBB->begin(), ENext = NextBB->end(); - while (MBBINext != ENext) { - MachineBasicBlock::const_iterator NMBBINext = std::next(MBBINext); - const MachineInstr &MINext = *MBBINext; - if (MINext.getOpcode() == XVM::END_BLOCK || MINext.getOpcode() == XVM::END_LOOP) { - LevelBreakAfterLoop ++; - } else { - break; - } - MBBINext = NMBBINext; + if (NextBBIsSucc) { + MachineBasicBlock::const_iterator MBBINext = NextBB->begin(), ENext = NextBB->end(); + while (MBBINext != ENext) { + MachineBasicBlock::const_iterator NMBBINext = std::next(MBBINext); + const MachineInstr &MINext = *MBBINext; + if (MINext.getOpcode() == XVM::END_BLOCK || MINext.getOpcode() == XVM::END_LOOP) { + LevelBreakAfterLoop ++; + } else { + break; + } + MBBINext = NMBBINext; + } } } } - MachineInstr *MIThen = MBB.getParent()->CreateMachineInstr(TII->get(XVM::THEN), DebugLoc()); MBB.insertAfter(MI.getIterator(), MIThen); MachineInstr *MIAction = MBB.getParent()->CreateMachineInstr(TII->get(action_opcode), DebugLoc()); MBB.insertAfter(MIThen->getIterator(), MIAction); - MachineInstrBuilder MIB(MF, MIAction); - if (BreakImmValue > -1 && action_opcode == XVM::BREAK_IMM) - MIB.addImm(BreakImmValue); MachineInstr *MIEndThen = MBB.getParent()->CreateMachineInstr(TII->get(XVM::END_THEN), DebugLoc()); MBB.insertAfter(MIAction->getIterator(), MIEndThen); if (LevelBreakAfterLoop >= 0) { @@ -338,10 +323,18 @@ void XVMCFGStackify::registerScope(MachineInstr *Begin, EndToBegin[End] = Begin; } +void XVMCFGStackify::unregisterScope(MachineInstr *Begin) { + assert(BeginToEnd.count(Begin)); + MachineInstr *End = BeginToEnd[Begin]; + assert(EndToBegin.count(End)); + BeginToEnd.erase(Begin); + EndToBegin.erase(End); +} + static bool isChild(const MachineInstr &MI) { if (MI.getNumOperands() == 0) return false; - const MachineOperand &MO = MI.getOperand(MO_FIRST); + const MachineOperand &MO = MI.getOperand(0); if (!MO.isReg() || MO.isImplicit() || !MO.isDef()) return false; Register Reg = MO.getReg(); @@ -355,60 +348,30 @@ static bool isChild(const MachineInstr &MI) { * Note: we may find other approach for fixing this. */ unsigned XVMCFGStackify::getBranchDepth( - MachineFunction &MF, - const MachineBasicBlock *MBB, - MachineInstr *MI) { - - int depth = -1; - int baseMBBnum = MI->getParent()->getNumber(); - auto MBBI = MF.begin(); - int targetMBBnum = MBB->getNumber(); - - while (MBBI->getNumber() != baseMBBnum) { - MBBI++; - } - - MBBI++; - - while (MBBI != MF.end()) { - MachineBasicBlock &CurMBB = *MBBI; - if (CurMBB.getNumber() == targetMBBnum) { - /* We are in the correct MBB, go to the first real instruction */ - for (auto MII = CurMBB.begin(); MII != CurMBB.end(); MII++) { - MachineInstr &CurMI = *MII; - if (CurMI.getOpcode() == XVM::END_LOOP || CurMI.getOpcode() == XVM::END_BLOCK) { - depth++; - } else { - return depth; - } - } - } else { - /* We are not in the right MBB yet, count all the loop and block markers - * Additionally check if any of these end_loops lead to the correct basic block - */ - for (auto MII = CurMBB.begin(); MII != CurMBB.end(); MII++) { - MachineInstr &CurMI = *MII; - if (CurMI.getOpcode() == XVM::LOOP || CurMI.getOpcode() == XVM::BLOCK) { - depth--; - } else if (CurMI.getOpcode() == XVM::END_BLOCK) { - depth++; - } else if (CurMI.getOpcode() == XVM::END_LOOP) { - /* Check if this ENDLOOP goes to the right MBB */ - if (EndLoopToMBBnum[&CurMI] == targetMBBnum) { - return depth; - } else { - depth++; - } - } - } + const SmallVectorImpl &Stack, + const std::set *SetEndBlockLoop, + const MachineBasicBlock *MBB) { + unsigned Depth = 0; + for (auto X : reverse(Stack)) { + if (X.first == MBB) { + std::set::iterator I = SetEndBlockLoop->find(MBB); + if (I != SetEndBlockLoop->end()) + ++Depth; + break; } - MBBI++; + ++Depth; } - - return depth; + assert(Depth < Stack.size() && "Branch destination should be in scope"); + return Depth; } - +static inline MachineBasicBlock *getNextBlock(MachineBasicBlock &MBB) { + MachineFunction::iterator I = MBB.getIterator(); + MachineFunction::iterator E = MBB.getParent()->end(); + if (++I == E) + return nullptr; + return &*I; +} static inline MachineInstr *getNextInstruction(MachineInstr &MI) { MachineBasicBlock::iterator I = MI.getIterator(); @@ -748,39 +711,66 @@ void XVMCFGStackify::rewriteDepthImmediates(MachineFunction &MF) { // Now rewrite references to basic blocks to be depth immediates. std::map CondBranchsWithDepth; TII = MF.getSubtarget().getInstrInfo(); - int TargetMBB; - + SmallVector Stack; + std::set SetEndBlockLoop; + SmallVector EHPadStack; for (auto &MBB : reverse(MF)) { for (MachineInstr &MI : llvm::reverse(MBB)) { - if (MI.isTerminator()) { - // Rewrite MBB operands to be depth immediates. - SmallVector Ops(MI.operands()); - unsigned int Opcode = MI.getOpcode(); - unsigned int Depth = 0; - while (MI.getNumOperands() > 0) - MI.removeOperand(MI.getNumOperands() - 1); - for (auto MO : Ops) { - if (MO.isMBB()) { - TargetMBB = MO.getMBB()->getNumber(); - Depth = getBranchDepth(MF, MO.getMBB(), &MI); - MO = MachineOperand::CreateImm(Depth); + switch (MI.getOpcode()) { + case XVM::BLOCK: + assert(ScopeTops[Stack.back().first->getNumber()]->getNumber() <= + MBB.getNumber() && + "Block/try marker should be balanced"); + Stack.pop_back(); + break; + + case XVM::LOOP: + assert(Stack.back().first == &MBB && "Loop top should be balanced"); + Stack.pop_back(); + break; + + case XVM::END_BLOCK: + Stack.push_back(std::make_pair(&MBB, &MI)); + break; + + case XVM::END_LOOP: { + Stack.push_back(std::make_pair(EndToBegin[&MI]->getParent(), &MI)); + MachineInstr *PrevMI = MI.getPrevNode(); + if (PrevMI != NULL) { + if (PrevMI->getOpcode() == XVM::END_BLOCK || PrevMI->getOpcode() == XVM::END_LOOP) { + SetEndBlockLoop.insert(&MBB); } - MI.addOperand(MF, MO); } - if (Opcode == XVM::BR) { - if (Depth == -1 && ContinueMap[&MI] == TargetMBB) { - MI.setDesc(TII->get(XVM::CONTINUE)); - } else { + break; + } + default: + if (MI.isTerminator()) { + // Rewrite MBB operands to be depth immediates. + SmallVector Ops(MI.operands()); + unsigned int Opcode = MI.getOpcode(); + unsigned int depth = 0; + while (MI.getNumOperands() > 0) + MI.removeOperand(MI.getNumOperands() - 1); + for (auto MO : Ops) { + if (MO.isMBB()) { + depth = getBranchDepth(Stack, &SetEndBlockLoop, MO.getMBB()); + MO = MachineOperand::CreateImm(depth); + } + MI.addOperand(MF, MO); + } + if (Opcode == XVM::BR) { MI.setDesc(TII->get(XVM::BREAK_IMM)); + } else if (TII->isCondBranch(&MI) && !TII->isCondBranchProcessed(&MI)) { + /** add the following instructions: THEN, BRREAK_IMM and END_THEN */ + CondBranchsWithDepth.insert(std::make_pair(&MI, depth)); } - } else if (TII->isCondBranch(&MI) && !TII->isCondBranchProcessed(&MI)) { - /** add the following instructions: THEN, BRREAK_IMM and END_THEN */ - CondBranchsWithDepth.insert(std::make_pair(&MI, Depth)); } + break; } } } extendCondStmt(CondBranchsWithDepth, MF); + assert(Stack.empty() && "Control flow should be balanced"); } void XVMCFGStackify::cleanupFunctionData(MachineFunction &MF) { @@ -795,33 +785,15 @@ void XVMCFGStackify::releaseMemory() { EndToBegin.clear(); } -void XVMCFGStackify::fillEndLoopMap(MachineFunction &MF) { - std::vector stack; - stack.push_back(-1); - for (auto &MBB : MF) { - for (MachineInstr &MI : MBB) { - if (MI.getOpcode() == XVM::LOOP) { - stack.push_back(MBB.getNumber()); - } else if (MI.getOpcode() == XVM::END_LOOP) { - EndLoopToMBBnum[&MI] = EndToBegin[&MI]->getParent()->getNumber(); - stack.pop_back(); - } else { - ContinueMap[&MI] = stack.back(); - } - } - } -} - bool XVMCFGStackify::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n" "********** Function: " << MF.getName() << '\n'); releaseMemory(); + // Place the BLOCK/LOOP/TRY markers to indicate the beginnings of scopes. placeMarkers(MF); - fillEndLoopMap(MF); - // Place the continue statements for each backedge of loops. fixBackEdgesOfLoops(MF); diff --git a/llvm/lib/Target/XVM/XVMISelLowering.cpp b/llvm/lib/Target/XVM/XVMISelLowering.cpp index 11e92863c0b7..179486601186 100644 --- a/llvm/lib/Target/XVM/XVMISelLowering.cpp +++ b/llvm/lib/Target/XVM/XVMISelLowering.cpp @@ -715,7 +715,7 @@ SDValue XVMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const { CondV.getOpcode() == ISD::XOR || CondV.getOpcode() == ISD::Constant || CondV.getOpcode() == ISD::UADDO || CondV.getOpcode() == ISD::SELECT_CC || CondV.getOpcode() == ISD::UREM || CondV.getOpcode() == ISD::SRL || - CondV.getOpcode() == ISD::SELECT || CondV.getOpcode() == ISD::SREM) { + CondV.getOpcode() == ISD::SELECT) { SDValue LHS = CondV; SDValue RHS = DAG.getConstant(0, DL, MVT::i64); SDValue TargetCC = DAG.getCondCode(ISD::SETNE); diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.td b/llvm/lib/Target/XVM/XVMInstrInfo.td index 2a0fc34c246e..09e5e0d6f0d3 100644 --- a/llvm/lib/Target/XVM/XVMInstrInfo.td +++ b/llvm/lib/Target/XVM/XVMInstrInfo.td @@ -189,7 +189,7 @@ let isBranch = 1, hasCtrlDep = 1 in { def BREAK_IMM : ControFlowNoArgs<0b00001000, (outs), (ins uimm6:$imm), "break #$imm", []>; def CONTINUE : ControFlowNoArgs<0b00000000, (outs), (ins), "continue", []>; def THEN : ControFlowNoArgs<0b00000000, (outs), (ins), "(then", []>; - def END_THEN : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; + def END_THEN : ControFlowNoArgs<0b00000000, (outs), (ins), ") ;; end_then", []>; def ELSE : ControFlowNoArgs<0b00000000, (outs), (ins), "(else", []>; def END_ELSE : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; def END_IF : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; @@ -458,4 +458,4 @@ def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETLT, bb:$dst), def : Pat<(XVMbrccri i64:$op1, imm:$op2, SETULT, bb:$dst), (BULT_ri bb:$dst, XVMGPR:$op1, uimm16:$op2)>; -include "XVMInstrBulkMemory.td" +include "XVMInstrBulkMemory.td" \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMRegisterInfo.cpp b/llvm/lib/Target/XVM/XVMRegisterInfo.cpp index 49d41e471861..9c08b9efcd8f 100644 --- a/llvm/lib/Target/XVM/XVMRegisterInfo.cpp +++ b/llvm/lib/Target/XVM/XVMRegisterInfo.cpp @@ -93,24 +93,22 @@ void XVMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBIterato * Therefore, we use SP+(Stacksize + FP_offset) to mimic (FP + FP_offset) */ auto &MFI = MFunction.getFrameInfo(); - int64_t StackSize = (int64_t)MFI.getStackSize(); - int Offset = 0; + uint64_t StackSize = MFI.getStackSize(); if (MInstr.getOpcode() == XVM::MOV_rr) { - Offset = MFunction.getFrameInfo().getObjectOffset(FrameIndex); + int Offset = MFunction.getFrameInfo().getObjectOffset(FrameIndex); WarnSize(Offset, MFunction, DLoc); Register reg = MInstr.getOperand(counter - 1).getReg(); BuildMI(MBBlock, ++MBBIterator, DLoc, TII.get(XVM::MOV_rr), reg).addReg(XVM::SP); - if (StackSize + Offset > 0) { + if (StackSize + Offset) { BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); - } else { - BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::SubRef_ri), reg).addReg(reg).addImm(-(StackSize + Offset)); } MInstr.eraseFromParent(); return; } - Offset = MFunction.getFrameInfo().getObjectOffset(FrameIndex) + MInstr.getOperand(counter + 1).getImm(); + int Offset = MFunction.getFrameInfo().getObjectOffset(FrameIndex) + + MInstr.getOperand(counter + 1).getImm(); if (!isInt(Offset)) llvm_unreachable("bug in frame offset"); @@ -123,11 +121,7 @@ void XVMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBIterato // ADD_ri , imm Register reg = MInstr.getOperand(counter - 1).getReg(); BuildMI(MBBlock, ++MBBIterator, DLoc, TII.get(XVM::MOV_rr), reg).addReg(FrameReg); - if (StackSize + Offset > 0) { - BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); - } else { - BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::SubRef_ri), reg).addReg(reg).addImm(-(StackSize + Offset)); - } + BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); // Remove FI_ri instruction MInstr.eraseFromParent(); diff --git a/llvm/lib/Target/XVM/XVMTargetMachine.cpp b/llvm/lib/Target/XVM/XVMTargetMachine.cpp index 40aaec7808e6..f136c1dd3382 100644 --- a/llvm/lib/Target/XVM/XVMTargetMachine.cpp +++ b/llvm/lib/Target/XVM/XVMTargetMachine.cpp @@ -27,10 +27,6 @@ #include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Vectorize.h" #include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/InstCombine/InstCombine.h" -#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h" -#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h" - using namespace llvm; @@ -47,37 +43,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTarget() { initializeXVMUpdateRefInstrForMIPass(PR); initializeDSELegacyPassPass(PR); initializeJumpThreadingPass(PR); - - initializeMachineCSEPass(PR); - initializeCorrelatedValuePropagationPass(PR); - initializeInstructionCombiningPassPass(PR); - initializeSimpleLoopUnswitchLegacyPassPass(PR); - initializeAggressiveInstCombinerLegacyPassPass(PR); - - initializeCallSiteSplittingLegacyPassPass(PR); - initializeFunctionSpecializationLegacyPassPass(PR); - - - initializeConstantMergeLegacyPassPass(PR); - initializeGlobalDCELegacyPassPass(PR); - initializeEliminateAvailableExternallyLegacyPassPass(PR); - initializeGVNLegacyPassPass(PR); - - initializeLoopUnrollAndJamPass(PR); - initializeLoopUnrollPass(PR); - - // initializeLoopFuseLegacyPass(PR); - initializeLoopDataPrefetchLegacyPassPass(PR); - initializeLoopDeletionLegacyPassPass(PR); - initializeLoopAccessLegacyAnalysisPass(PR); - initializeLoopInstSimplifyLegacyPassPass(PR); - initializeLoopInterchangeLegacyPassPass(PR); - initializeLoopFlattenLegacyPassPass(PR); - initializeLoopPredicationLegacyPassPass(PR); - initializeLoopRotateLegacyPassPass(PR); - initializeLoopStrengthReducePass(PR); - - // initializeBasicBlockSectionsPass(PR); } extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTargetCalledInDylib() { @@ -139,35 +104,6 @@ bool XVMPassConfig::addPreISel() { addPass(createJumpThreadingPass(-1)); addPass(createSpeculativeExecutionPass()); addPass(createMergedLoadStoreMotionPass()); - - addPass(createEarlyCSEPass()); - addPass(createCorrelatedValuePropagationPass()); - addPass(createInstructionCombiningPass()); - addPass(createSimpleLoopUnswitchLegacyPass(true)); - addPass(createAggressiveInstCombinerPass()); - addPass(createCallSiteSplittingPass()); - addPass(createFunctionSpecializationPass()); - - addPass(createConstantMergePass()); - addPass(createGlobalDCEPass()); - addPass(createEliminateAvailableExternallyPass()); - addPass(createTailCallEliminationPass()); - addPass(createGVNPass(false)); - - addPass(createLoopUnrollAndJamPass(3)); - addPass(createLoopUnrollPass(3)); - - // addPass(createLoopFusePass()); - addPass(createLoopDataPrefetchPass()); - addPass(createLoopDeletionPass()); - // addPass(createLoopAccessLegacyAnalysisPass()); - addPass(createLoopInstSimplifyPass()); - addPass(createLoopInterchangePass()); - addPass(createLoopFlattenPass()); - addPass(createLoopPredicationPass()); - addPass(createLoopRotatePass()); - addPass(createLoopStrengthReducePass()); - return false; } @@ -201,8 +137,6 @@ void XVMPassConfig::addPreEmitPass() { // Sort the blocks of the CFG into topological order, // a prerequisite for BLOCK and LOOP markers. // Currently, the algorithm is from WebAssembly. - - // addPass(createBasicBlockSectionsPass()); addPass(createXVMCFGSort()); addPass(createXVMCFGStackify()); } diff --git a/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp b/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp index 6b9fbc6dbe9f..4838884ca14d 100644 --- a/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp +++ b/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp @@ -51,14 +51,12 @@ public: StringRef getPassName() const override { return XVM_REF_DETERMINE_NAME; } private: bool scanRefInfoInMBB(MachineBasicBlock &MBB); - bool forceShiftRefInfoIbMBB(MachineBasicBlock &MBB); - bool forceAddSubRefInfoIbMBB(MachineBasicBlock &MBB); bool updateRefInfoBasedInMBB(MachineBasicBlock &MBB); + bool checkAndUpdateOrInMBB(MachineBasicBlock &MBB); void updatePtrRefInMBB(MachineBasicBlock &MBB); void doubleCheckPhiMIWithRef(MachineBasicBlock &MBB); void doubleCheckRefs(MachineBasicBlock &MBB); - void checkAndReplaceAddWithAddRefs(MachineBasicBlock &MBB); bool updateRegistersOfMIInMBB(MachineBasicBlock &MBB); bool finalFixRefs(void); void FindNonRefRegInFunc(const MachineFunction &MF); @@ -304,6 +302,17 @@ static bool updateLoadMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { return false; } +static void checkAddSubMIWithRef(MachineInstr &MI) { + if (MI.getOpcode() == XVM::ADD_ri || MI.getOpcode() == XVM::ADD_rr || + MI.getOpcode() == XVM::SUB_ri || MI.getOpcode() == XVM::SUB_rr) { + assert(MI.getNumOperands() == NUM_MO_3); + MachineOperand &MO_def = MI.getOperand(MO_FIRST); + MachineOperand &MO_use = MI.getOperand(MO_SECOND); + setRefFlagFor2Ops(MO_def, MO_use); + return; + } +} + static void checkOrXorAndMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::OR_ri || MI.getOpcode() == XVM::XOR_ri|| @@ -391,7 +400,7 @@ static inline bool updateAddMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) updateAddRiWithRef(MI, TII); } else { // It may be the case there use2 is a ref while use1 is not a ref - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); + MachineOperand &MO_use2 = MI.getOperand(2); Register regNoUse1 = MO_use1.getReg(); Register regNoUse2 = MO_use2.getReg(); std::map::iterator ItrUse1 = MapRefRegInFunc.find(regNoUse1); @@ -410,14 +419,13 @@ static inline bool updateAddMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) MachineRegisterInfo &MRI = MF->getRegInfo(); MachineInstr *ReplaceMI = BuildMI(MBB, II, DL, TII->get(XVM::AddRef_rr)); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use1 = MI.getOperand(1); + MachineOperand &MO_use2 = MI.getOperand(2); ReplaceMI->addOperand(MO_def); ReplaceMI->addOperand(MO_use2); ReplaceMI->addOperand(MO_use1); - MBB.remove_instr(&MI); MRI.verifyUseLists(); } else { @@ -558,9 +566,9 @@ static inline bool switchOperandUse1Use2(MachineBasicBlock &MBB, MachineInstr &M MachineRegisterInfo &MRI = MF->getRegInfo(); MachineInstr *ReplaceMI = BuildMI(MBB, II, DL, TII->get(MI.getOpcode())); - MachineOperand &NewMO_def = MI.getOperand(MO_FIRST); - MachineOperand &NewMO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &NewMO_use2 = MI.getOperand(MO_THIRD); + MachineOperand &NewMO_def = MI.getOperand(0); + MachineOperand &NewMO_use1 = MI.getOperand(1); + MachineOperand &NewMO_use2 = MI.getOperand(2); ReplaceMI->addOperand(NewMO_def); ReplaceMI->addOperand(NewMO_use2); @@ -571,8 +579,6 @@ static inline bool switchOperandUse1Use2(MachineBasicBlock &MBB, MachineInstr &M } } } - - return false; } static inline bool updateOrMIWithRef(MachineBasicBlock &MBB, MachineInstr &MI, const XVMInstrInfo *TII) { @@ -944,15 +950,6 @@ static void checkPhiMIWithRef(MachineInstr &MI) { } } -static void checkFIMIWithRef(MachineInstr &MI) { - if (MI.getOpcode() == XVM::FI_ri) { - assert(NUM_MO_3 == MI.getNumOperands()); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - if (MO_def.isReg()) - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - } -} - static bool updatePhiMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { /* No update for Phi*/ return false; @@ -1135,20 +1132,10 @@ bool XVMUpdateRefInstrForMI::runOnMachineFunction(MachineFunction &MF) { FindNonRefRegInFunc(MF); bool Modified = false; - // force the ref info for shift MIs in MBB - for (auto &MBB : MF) { - Modified |= forceShiftRefInfoIbMBB(MBB); - } // scan MBBs in MF for (auto &MBB : MF) { Modified |= scanRefInfoInMBB(MBB); } - - // force the ref info for Add_rr MIs in MBB - for (auto &MBB : MF) { - Modified |= forceAddSubRefInfoIbMBB(MBB); - } - // update MBBs in MF for (auto &MBB : MF) { Modified |= updateRefInfoBasedInMBB(MBB); @@ -1164,9 +1151,6 @@ bool XVMUpdateRefInstrForMI::runOnMachineFunction(MachineFunction &MF) { } Modified |= finalFixRefs(); - for (auto &MBB : MF) { - checkAndReplaceAddWithAddRefs(MBB); - } return Modified; } @@ -1179,7 +1163,7 @@ bool XVMUpdateRefInstrForMI::finalFixRefs(void) { MachineOperand &MO_def = MI->getOperand(MO_FIRST); if (!MO_def.isReg()) - continue; + return Modified; Register regNoDef = MO_def.getReg(); std::map::iterator IForDef = MapRefRegInFunc.find(regNoDef); @@ -1205,7 +1189,7 @@ bool XVMUpdateRefInstrForMI::finalFixRefs(void) { SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); Modified = true; // Switch the use 1 with use 2 if use 2 is a ref - MachineOperand &MO_use2 = MI->getOperand(MO_THIRD); + MachineOperand &MO_use2 = MI->getOperand(2); Register regNoUse2 = MO_use2.getReg(); std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); if (IForUse2 != MapRefRegInFunc.end()) { @@ -1218,9 +1202,9 @@ bool XVMUpdateRefInstrForMI::finalFixRefs(void) { MachineRegisterInfo &MRI = MF->getRegInfo(); MachineInstr *ReplaceMI = BuildMI(*MBB, II, DL, TII->get(XVM::AddRef_rr)); - MachineOperand &NewMO_def = MI->getOperand(MO_FIRST); - MachineOperand &NewMO_use1 = MI->getOperand(MO_SECOND); - MachineOperand &NewMO_use2 = MI->getOperand(MO_THIRD); + MachineOperand &NewMO_def = MI->getOperand(0); + MachineOperand &NewMO_use1 = MI->getOperand(1); + MachineOperand &NewMO_use2 = MI->getOperand(2); ReplaceMI->addOperand(NewMO_def); ReplaceMI->addOperand(NewMO_use2); @@ -1274,54 +1258,6 @@ bool XVMUpdateRefInstrForMI::finalFixRefs(void) { return Modified; } -void XVMUpdateRefInstrForMI::checkAndReplaceAddWithAddRefs(MachineBasicBlock &MBB) { - MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); - int InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - if (MI.getNumOperands() < 2) { - MBBI = NMBBI; - continue; - } - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - if (!MO_def.isReg()) { - MBBI = NMBBI; - continue; - } - const MachineFunction *F = MI.getParent()->getParent(); - switch (MI.getOpcode()) { - case XVM::ADD_rr: { - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - Register regNoDef = MO_def.getReg(); - std::map::iterator IForDef = MapRefRegInFunc.find(regNoDef); - Register regNoUse1 = MO_use1.getReg(); - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - bool DefOrUseIsRef = false; - - if ((IForDef != MapRefRegInFunc.end() && IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) || - (IForUse1 != MapRefRegInFunc.end() && IForUse1->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse1) == SetNonRefRegInFunc.end()) || - (IForUse2 != MapRefRegInFunc.end() && IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end())) { - DefOrUseIsRef = true; - } - if (DefOrUseIsRef) { - MI.setDesc(TII->get(XVM::AddRef_rr)); - } - break; - } - default: - break; - } - MBBI = NMBBI; - } -} - void XVMUpdateRefInstrForMI::doubleCheckRefs(MachineBasicBlock &MBB) { MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); int InstNumber = std::distance(MBB.begin(), MBB.end()); @@ -1793,8 +1729,8 @@ bool XVMUpdateRefInstrForMI::scanRefInfoInMBB(MachineBasicBlock &MBB) { checkMovMIWithRef(MI); checkLoadMIWithRef(MI); checkStoreMIWithRef(MI); + checkAddSubMIWithRef(MI); checkPhiMIWithRef(MI); - checkFIMIWithRef(MI); R_MBBI = NMBBI; } // normal order @@ -1807,116 +1743,13 @@ bool XVMUpdateRefInstrForMI::scanRefInfoInMBB(MachineBasicBlock &MBB) { checkMovMIWithRef(MI); checkLoadMIWithRef(MI); checkStoreMIWithRef(MI); + checkAddSubMIWithRef(MI); checkPhiMIWithRef(MI); MBBI = NMBBI; } return Modified; } -static void forceShiftMIWithRef(MachineInstr &MI) { - if (MI.getOpcode() == XVM::LSL_ri || MI.getOpcode() == XVM::ASR_ri) { - assert(MI.getNumOperands() == NUM_MO_3); - // Force the def and use registers are non-ref - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); - SetRegTypeForMO(MO_def, XVM_SYM_REG_NON_REF); - SetRegTypeForMO(MO_use, XVM_SYM_REG_NON_REF); - SetNonRefRegInFunc.insert(MO_def.getReg()); - SetNonRefRegInFunc.insert(MO_use.getReg()); - return; - } - - if (MI.getOpcode() == XVM::LSL_rr || MI.getOpcode() == XVM::ASR_rr) { - assert(MI.getNumOperands() == NUM_MO_3); - // Force the def and use registers are non-ref - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - SetRegTypeForMO(MO_def, XVM_SYM_REG_NON_REF); - SetRegTypeForMO(MO_use1, XVM_SYM_REG_NON_REF); - SetRegTypeForMO(MO_use2, XVM_SYM_REG_NON_REF); - SetNonRefRegInFunc.insert(MO_def.getReg()); - SetNonRefRegInFunc.insert(MO_use1.getReg()); - SetNonRefRegInFunc.insert(MO_use2.getReg()); - return; - } -} - -bool XVMUpdateRefInstrForMI::forceShiftRefInfoIbMBB(MachineBasicBlock &MBB) { - int InstNumber = 0; - bool Modified = false; - - // reverse order - MachineBasicBlock::reverse_iterator R_MBBI = MBB.rbegin(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::reverse_iterator NMBBI = std::next(R_MBBI); - MachineInstr &MI = *R_MBBI; - forceShiftMIWithRef(MI); - R_MBBI = NMBBI; - } - // normal order - MachineBasicBlock::iterator MBBI = MBB.begin(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - forceShiftMIWithRef(MI); - MBBI = NMBBI; - } - return Modified; -} - -bool XVMUpdateRefInstrForMI::forceAddSubRefInfoIbMBB(MachineBasicBlock &MBB) { - int InstNumber = 0; - bool Modified = false; - - MachineBasicBlock::iterator MBBI = MBB.begin(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - if (MI.getOpcode() == XVM::ADD_rr) { - assert(MI.getNumOperands() == NUM_MO_3); - // if def is ref and use1 is not ref: - // then use2 should be a ref - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - Register regNoDef = MO_def.getReg(); - Register regNo1 = MO_use1.getReg(); - Register regNo2 = MO_use2.getReg(); - std::map::iterator IDef = MapRefRegInFunc.find(regNoDef); - std::map::iterator IUse1 = MapRefRegInFunc.find(regNo1); - std::map::iterator IUse2 = MapRefRegInFunc.find(regNo2); - - if (IDef != MapRefRegInFunc.end() && IDef->second == XVM_SYM_REG_REF) { - // now def is a ref - if (SetNonRefRegInFunc.find(regNo1) != SetNonRefRegInFunc.end()) { - // now use1 is not a ref: set use2 as a ref - MapRefRegInFunc[regNo2] = XVM_SYM_REG_REF; - // Need to Switch: will be catched in the next phases - } - } else if (IDef == MapRefRegInFunc.end() || IDef->second == XVM_SYM_REG_NON_REF) { - // now def is not a ref - if (MapRefRegInFunc[regNo1] == XVM_SYM_REG_REF || MapRefRegInFunc[regNo2] == XVM_SYM_REG_REF) { - // Now either use1 is ref or use2 is ref: def has to be ref - MapRefRegInFunc[regNoDef] = XVM_SYM_REG_REF; - } - } - } else if (MI.getOpcode() == XVM::ADD_ri || - MI.getOpcode() == XVM::SUB_ri || - MI.getOpcode() == XVM::SUB_rr) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); - setRefFlagFor2Ops(MO_def, MO_use); - } - MBBI = NMBBI; - } - return Modified; -} - bool XVMUpdateRefInstrForMI::updateRefInfoBasedInMBB(MachineBasicBlock &MBB) { int InstNumber = 0; bool Modified = false; @@ -1972,7 +1805,7 @@ bool XVMUpdateRefInstrForMI::updateRefInfoBasedInMBB(MachineBasicBlock &MBB) { continue; } } - + return Modified; } -- Gitee From 38344a131cdf015e440fe3d7581073155d7a9289 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 21 Jun 2025 10:07:12 +0800 Subject: [PATCH 4/4] Revert "[XVM] Bug Fixes" This reverts commit 0803eea97984f8ef0f881e01a475cdaa189ca2df. Signed-off-by: Eric --- clang/lib/CodeGen/TargetInfo.cpp | 5 - llvm-build/build.py | 43 +- llvm/lib/Target/XVM/CMakeLists.txt | 2 - .../XVM/MCTargetDesc/XVMInstPrinter.cpp | 103 +- .../Target/XVM/MCTargetDesc/XVMInstPrinter.h | 12 +- .../XVM/MCTargetDesc/XVMMCTargetDesc.cpp | 1 - llvm/lib/Target/XVM/XVMAsmPrinter.cpp | 207 +-- llvm/lib/Target/XVM/XVMCFGSort.cpp | 367 ++-- llvm/lib/Target/XVM/XVMCFGStackify.cpp | 535 +++--- llvm/lib/Target/XVM/XVMCFGStructure.cpp | 6 +- llvm/lib/Target/XVM/XVMErrorMsg.h | 43 - llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp | 22 +- llvm/lib/Target/XVM/XVMFrameLowering.cpp | 9 +- llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp | 139 +- llvm/lib/Target/XVM/XVMISelLowering.cpp | 822 +++++---- llvm/lib/Target/XVM/XVMISelLowering.h | 20 +- llvm/lib/Target/XVM/XVMInstrInfo.cpp | 156 +- llvm/lib/Target/XVM/XVMInstrInfo.h | 3 +- llvm/lib/Target/XVM/XVMInstrInfo.td | 12 +- llvm/lib/Target/XVM/XVMMCInstLower.cpp | 44 +- llvm/lib/Target/XVM/XVMRegisterInfo.cpp | 97 +- llvm/lib/Target/XVM/XVMRegisterInfo.h | 4 +- llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp | 1 - llvm/lib/Target/XVM/XVMSubtarget.cpp | 1 + llvm/lib/Target/XVM/XVMTargetMachine.cpp | 49 +- llvm/lib/Target/XVM/XVMTargetMachine.h | 8 +- llvm/lib/Target/XVM/XVMTargetTransformInfo.h | 13 +- .../lib/Target/XVM/XVMUpdateRefInstrForMI.cpp | 1524 ++++------------- llvm/lib/Target/XVM/XVM_def.h | 18 - 29 files changed, 1600 insertions(+), 2666 deletions(-) delete mode 100644 llvm/lib/Target/XVM/XVMErrorMsg.h diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 53b623819d8b..fc8fca3fe463 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5537,11 +5537,6 @@ public: llvm::AttrBuilder B(GV->getContext()); B.addAttribute("xvm-export-name", Attr->getExportName()); Fn->addFnAttrs(B); - } else { - if (FD->isStatic()) { - llvm::Function *Fn = cast(GV); - Fn->addFnAttr(llvm::Attribute::AlwaysInline); - } } } } diff --git a/llvm-build/build.py b/llvm-build/build.py index 0984791283e8..f95a288491fd 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -775,7 +775,6 @@ class LlvmCore(BuildUtils): build_dir, install_dir, build_name, - need_compiler_rt, build_target=None, extra_defines=None, extra_env=None): @@ -817,11 +816,10 @@ class LlvmCore(BuildUtils): # First of all build compiler-rt because it's needed to be built before libunwind and etc. if not self.build_config.build_only and not 'windows-x86_64' in build_dir: - if need_compiler_rt: - self.invoke_ninja(out_path=build_dir, - env=env, - target=["compiler-rt"], - install=install) + self.invoke_ninja(out_path=build_dir, + env=env, + target=["compiler-rt"], + install=install) self.invoke_ninja(out_path=build_dir, env=env, @@ -988,25 +986,22 @@ class LlvmCore(BuildUtils): if self.build_config.enable_monitoring: llvm_defines['LLDB_ENABLE_PERFORMANCE'] = 'ON' - def llvm_build_install_xvm_dylib_so(self, targets, - build_name, + def llvm_build_install_xvm_dylib_so(self, build_name, out_dir, build_target, llvm_extra_env, - debug_build, - llvm_defines): + debug_build): llvm_path = self.merge_out_path('llvm_make') llvm_path_dylib_so = self.merge_out_path('llvm_make_dylib_so') install_dir_dylib_so = self.merge_out_path('llvm-install-dylib-so') - llvm_defines_dylib_so = llvm_defines + llvm_defines_dylib_so = {} llvm_defines_dylib_so['LLVM_SPLIT_LLVM_DYLIB_TARGETS'] = 'ON' if debug_build: llvm_defines_dylib_so['CMAKE_BUILD_TYPE'] = 'Debug' - self.build_llvm(targets='AArch64;X86;XVM', + self.build_llvm(targets='XVM', build_dir=llvm_path_dylib_so, install_dir=install_dir_dylib_so, build_name=build_name, - need_compiler_rt=False, build_target=build_target, extra_defines=llvm_defines_dylib_so, extra_env=llvm_extra_env) @@ -1096,18 +1091,15 @@ class LlvmCore(BuildUtils): build_dir=llvm_path, install_dir=out_dir, build_name=build_name, - need_compiler_rt=True, build_target=build_target, extra_defines=llvm_defines, extra_env=llvm_extra_env) if build_xvm: - self.llvm_build_install_xvm_dylib_so(target_list, - build_name, - out_dir, - build_target, - llvm_extra_env, - debug_build, - llvm_defines) + self.llvm_build_install_xvm_dylib_so(build_name, + out_dir, + build_target, + llvm_extra_env, + debug_build) def llvm_compile_windows_defines(self, windows_defines, @@ -1200,7 +1192,7 @@ class LlvmCore(BuildUtils): '-Wl,--gc-sections', '-stdlib=libc++', '--rtlib=compiler-rt', - '-lunwind', + '-lunwind', '-Wl,--dynamicbase', '-Wl,--nxcompat', '-lucrt', @@ -1290,7 +1282,6 @@ class LlvmCore(BuildUtils): build_dir, windows64_install, build_name, - need_compiler_rt=True, extra_defines=windows_defines, extra_env=windows_extra_env) @@ -2377,17 +2368,17 @@ class LlvmLibs(BuildUtils): if multilib_suffix: baseline_abi_file_path = self.merge_out_path(self.build_config.LLVM_BUILD_DIR, "libcxx_abidiff", llvm_triple, multilib_suffix, "libc++_shared.abi") - elf_common_path = self.merge_out_path('lib', + elf_common_path = self.merge_out_path('lib', f"libunwind-libcxxabi-libcxx-ndk-{str(llvm_triple)}-{multilib_suffix}", 'lib', llvm_triple, multilib_suffix) else: baseline_abi_file_path = self.merge_out_path(self.build_config.LLVM_BUILD_DIR, "libcxx_abidiff", llvm_triple, "libc++_shared.abi") - elf_common_path = self.merge_out_path('lib', + elf_common_path = self.merge_out_path('lib', f"libunwind-libcxxabi-libcxx-ndk-{str(llvm_triple)}", 'lib', llvm_triple) elf_file_path = self.merge_out_path(elf_common_path, "libc++_shared.so") abi_file_path = self.merge_out_path(elf_common_path, "libc++_shared.abi") - header_dir = self.merge_out_path('lib', + header_dir = self.merge_out_path('lib', f"libunwind-libcxxabi-libcxx-ndk-{str(llvm_triple)}", 'include', "c++", "v1") res = self.run_abi_check(elf_file_path, abi_file_path, baseline_abi_file_path, header_dir) if res: diff --git a/llvm/lib/Target/XVM/CMakeLists.txt b/llvm/lib/Target/XVM/CMakeLists.txt index 4f891b2895dd..f203cf837bb3 100644 --- a/llvm/lib/Target/XVM/CMakeLists.txt +++ b/llvm/lib/Target/XVM/CMakeLists.txt @@ -1,7 +1,6 @@ if(XVM IN_LIST LLVM_TARGETS_CALLED_VIA_DYLIB AND LLVM_SPLIT_LLVM_DYLIB_TARGETS) ADD_DEFINITIONS("-DXVM_DYLIB_MODE=1") - file(GLOB MCInstrAnalysisFN "${CMAKE_CURRENT_SOURCE_DIR}/../../MC/MCInstrAnalysis.cpp") endif() add_llvm_component_group(XVM) @@ -35,7 +34,6 @@ add_llvm_target(XVMCodeGen XVMExpandPseudoInsts.cpp XVMSelectionDAGInfo.cpp XVMUpdateRefInstrForMI.cpp - ${MCInstrAnalysisFN} LINK_COMPONENTS Analysis diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp index 79efd4ec38a4..2974ec81313c 100644 --- a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.cpp @@ -20,19 +20,14 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" - #define DEBUG_TYPE "asm-printer" #define GET_INSTRINFO_CTOR_DTOR // Include the auto-generated portion of the assembly writer. #include "XVMGenAsmWriter.inc" - using namespace llvm; using namespace std; -#define MIN_NUM_MO_CALL_INSTR 2 -#define MIN_NUM_MO_DATA_REF_INSTR 3 - void XVMInstPrinter::printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) { @@ -65,7 +60,7 @@ void XVMInstPrinter::printInst(const MCInst *MI, uint64_t Address, } void XVMInstPrinter::printCallInstructionImm(const MCInst *MI, raw_ostream &O) { - assert(MI->getNumOperands() >= MIN_NUM_MO_CALL_INSTR); + assert(MI->getNumOperands() >= 2); O << "\t"; auto MnemonicInfo = getMnemonic(MI); O << MnemonicInfo.first; @@ -86,7 +81,7 @@ void XVMInstPrinter::printMovWithFuncID(const MCInst *MI, raw_ostream &O) { } void XVMInstPrinter::printDataRefWithGlobalID(const MCInst *MI, raw_ostream &O) { - assert(MI->getNumOperands() >= MIN_NUM_MO_DATA_REF_INSTR); + assert(MI->getNumOperands() >= 3); const MCOperand &Op0 = MI->getOperand(0); assert(Op0.isReg()); const MCOperand &Op1 = MI->getOperand(1); @@ -98,7 +93,7 @@ void XVMInstPrinter::printDataRefWithGlobalID(const MCInst *MI, raw_ostream &O) } void XVMInstPrinter::printCallInstructionReg(const MCInst *MI, raw_ostream &O) { - assert(MI->getNumOperands() >= MIN_NUM_MO_CALL_INSTR); + assert(MI->getNumOperands() >= 2); O << "\t"; auto MnemonicInfo = getMnemonic(MI); O << MnemonicInfo.first; @@ -107,77 +102,79 @@ void XVMInstPrinter::printCallInstructionReg(const MCInst *MI, raw_ostream &O) { O << getRegisterName(MI->getOperand(1).getReg()); } -static void printExpr(const MCExpr *Expression, raw_ostream &OStream) { +static void printExpr(const MCExpr *Expr, raw_ostream &O) { #ifndef NDEBUG - const MCSymbolRefExpr *SRExpr; + const MCSymbolRefExpr *SRE; - if (const MCBinaryExpr *BExpr = dyn_cast(Expression)) - SRExpr = dyn_cast(BExpr->getLHS()); + if (const MCBinaryExpr *BE = dyn_cast(Expr)) + SRE = dyn_cast(BE->getLHS()); else - SRExpr = dyn_cast(Expression); - assert(SRExpr && "Unexpected MCExpr type."); + SRE = dyn_cast(Expr); + assert(SRE && "Unexpected MCExpr type."); - MCSymbolRefExpr::VariantKind VarKind = SRExpr->getKind(); + MCSymbolRefExpr::VariantKind Kind = SRE->getKind(); - assert(VarKind == MCSymbolRefExpr::VK_None); + assert(Kind == MCSymbolRefExpr::VK_None); #endif - OStream << *Expression; + O << *Expr; } -void XVMInstPrinter::printOperand(const MCInst *MInst, unsigned OpNum, - raw_ostream &OStream, const char *Mod) { - assert((Mod == nullptr || Mod[0] == 0) && "No modifiers supported"); - const MCOperand &Oper = MInst->getOperand(OpNum); - if (Oper.isReg()) { - OStream << getRegisterName(Oper.getReg()); - } else if (Oper.isImm()) { - OStream << formatImm((int32_t)Oper.getImm()); +void XVMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, const char *Modifier) { + assert((Modifier == nullptr || Modifier[0] == 0) && "No modifiers supported"); + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + O << getRegisterName(Op.getReg()); + } else if (Op.isImm()) { + O << formatImm((int32_t)Op.getImm()); } else { - assert(Oper.isExpr() && "Expected an expression"); - printExpr(Oper.getExpr(), OStream); + assert(Op.isExpr() && "Expected an expression"); + printExpr(Op.getExpr(), O); } } -void XVMInstPrinter::printMemOperand(const MCInst *MInst, int OpNum, - raw_ostream &OStream, const char *Mod) { - const MCOperand &ROp = MInst->getOperand(OpNum); - const MCOperand &OffOp = MInst->getOperand(OpNum + 1); +void XVMInstPrinter::printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O, + const char *Modifier) { + const MCOperand &RegOp = MI->getOperand(OpNo); + const MCOperand &OffsetOp = MI->getOperand(OpNo + 1); // register - assert(ROp.isReg() && "Register operand not a register"); - OStream << getRegisterName(ROp.getReg()); + assert(RegOp.isReg() && "Register operand not a register"); + O << getRegisterName(RegOp.getReg()); // offset - if (OffOp.isImm()) { - auto I = OffOp.getImm(); - if (I == 0) - OStream << ", #" << formatImm(I); + if (OffsetOp.isImm()) { + auto Imm = OffsetOp.getImm(); + if (Imm == 0) + O << ", #" << formatImm(Imm); else - OStream << ", #" << formatImm(I); + O << ", #" << formatImm(Imm); } else { assert(0 && "Expected an immediate"); } } -void XVMInstPrinter::printImm64Operand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream) { - const MCOperand &Oper = MInst->getOperand(OpNum); - if (Oper.isImm()) - OStream << formatImm(Oper.getImm()); - else if (Oper.isExpr()) - printExpr(Oper.getExpr(), OStream); +void XVMInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) + O << formatImm(Op.getImm()); + else if (Op.isExpr()) + printExpr(Op.getExpr(), O); else - OStream << Oper; + O << Op; } -void XVMInstPrinter::printBrTargetOperand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream) { - const MCOperand &Oper = MInst->getOperand(OpNum); - if (Oper.isImm()) { - int16_t I = Oper.getImm(); - OStream << ((I >= 0) ? "+" : "") << formatImm(I); - } else if (Oper.isExpr()) { - printExpr(Oper.getExpr(), OStream); +void XVMInstPrinter::printBrTargetOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) { + int16_t Imm = Op.getImm(); + O << ((Imm >= 0) ? "+" : "") << formatImm(Imm); + } else if (Op.isExpr()) { + printExpr(Op.getExpr(), O); } else { - OStream << Oper; + O << Op; } } diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h index abd335ba511b..33e8860810f0 100644 --- a/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMInstPrinter.h @@ -24,12 +24,12 @@ public: void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override; - void printOperand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream, - const char *Mod = nullptr); - void printMemOperand(const MCInst *MInst, int OpNum, raw_ostream &OStream, - const char *Mod = nullptr); - void printImm64Operand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream); - void printBrTargetOperand(const MCInst *MInst, unsigned OpNum, raw_ostream &OStream); + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, + const char *Modifier = nullptr); + void printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O, + const char *Modifier = nullptr); + void printImm64Operand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printCallInstructionImm(const MCInst *MI, raw_ostream &O); void printCallInstructionReg(const MCInst *MI, raw_ostream &O); diff --git a/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp index d95446097c7b..8480f9b8819c 100644 --- a/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp +++ b/llvm/lib/Target/XVM/MCTargetDesc/XVMMCTargetDesc.cpp @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// #ifdef XVM_DYLIB_MODE - #include "MCTargetDesc/XVMMCTargetDesc.h" #include "MCTargetDesc/XVMInstPrinter.h" #include "MCTargetDesc/XVMMCAsmInfo.h" diff --git a/llvm/lib/Target/XVM/XVMAsmPrinter.cpp b/llvm/lib/Target/XVM/XVMAsmPrinter.cpp index 97333b8e181f..30a67c159b83 100644 --- a/llvm/lib/Target/XVM/XVMAsmPrinter.cpp +++ b/llvm/lib/Target/XVM/XVMAsmPrinter.cpp @@ -17,7 +17,6 @@ #include "XVMInstrInfo.h" #include "XVMTargetMachine.h" #include "XVMMCInstLower.h" -#include "XVMErrorMsg.h" #include "MCTargetDesc/XVMInstPrinter.h" #include "TargetInfo/XVMTargetInfo.h" #include "llvm/Analysis/ConstantFolding.h" @@ -26,7 +25,6 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/IR/DiagnosticInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCStreamer.h" @@ -40,15 +38,6 @@ using namespace llvm; #define DEBUG_TYPE "asm-printer" -#define CHAT_LEN_IN_HEX 2 -#define REF_TYPE_LENGTH 8 -#define REF_TYPE_HEX_LENGTH 16 -#define NUM_BITS_PER_BYTE 8 -#define MAX_PTR_SIZE 8 -#define MAX_SIZE_CONSTANT_EXPRESSION 8 -#define INIT_SMALL_STR_SIZE 128 -#define NUM_MO_CTOR_DTOR 3 -#define MAX_FUNC_SIZE 32767 static cl::opt XVMExportAll("xvm-export-all", cl::Hidden, cl::init(false), @@ -98,18 +87,17 @@ private: void InitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, const Constant *BaseCV, - uint64_t Offset, XVMSectionInfo* SInfo, Module *M); + uint64_t Offset, XVMSectionInfo* SInfo); void InitGlobalConstantDataSequential(const DataLayout &DL, - const ConstantDataSequential *CDS, - XVMSectionInfo* SInfo); + const ConstantDataSequential *CDS, XVMSectionInfo* SInfo); void InitGlobalConstantArray(const DataLayout &DL, const ConstantArray *CA, const Constant *BaseCV, uint64_t Offset, - XVMSectionInfo* SInfo, Module *M); + XVMSectionInfo* SInfo); void InitGlobalConstantStruct(const DataLayout &DL, const ConstantStruct *CS, const Constant *BaseCV, uint64_t Offset, - XVMSectionInfo* SInfo, Module *M); + XVMSectionInfo* SInfo); }; } // namespace @@ -123,12 +111,13 @@ static std::map DataSectionNameIndexMap; static std::map DataSectionIndexInfoMap; template -inline std::string UnsignedIntTypeToHex(T V, size_t W = sizeof(T)*CHAT_LEN_IN_HEX) { +inline std::string UnsignedIntTypeToHex(T V, size_t W = sizeof(T)*2) +{ std::stringstream SS; std::string RS; SS << std::setfill('0') << std::setw(W) << std::hex << (V|0); - for (unsigned Index = 0; Index < SS.str().length(); Index = Index + CHAT_LEN_IN_HEX) { - RS += "\\x" + SS.str().substr(Index, CHAT_LEN_IN_HEX); + for (unsigned Index=0; Index>= NUM_BITS_PER_BYTE; + Input >>= 8; } return Result; } @@ -154,11 +143,10 @@ static inline uint64_t ReverseBytes(uint64_t Input, unsigned int Width) { #define DATA_SUB_SECTION 1 #define XVM_SD_SEG_START 4 -#define XVM_REF_OFFSET_BITS 44 static uint64_t CreateRefContent(int ToDataSecID, uint64_t ToOffset) { uint64_t seg_index = XVM_SD_SEG_START + ToDataSecID; uint64_t ReTRefData = 0; - ReTRefData = (seg_index & 0x00000000000FFFFF) << XVM_REF_OFFSET_BITS; + ReTRefData = (seg_index & 0x00000000000FFFFF) << 44; ReTRefData = ReTRefData | (ToOffset & 0x00000FFFFFFFFFFF); return ReTRefData; } @@ -330,13 +318,10 @@ static inline void PatchSectionInfo(void) { LLVM_DEBUG(dbgs() << "Add to Buf: " << UnsignedIntTypeToHex(ReverseBytes( CreateRefContent(DataSectionIndex, DataSectionOffset), - REF_TYPE_LENGTH), REF_TYPE_HEX_LENGTH).c_str() - << " size=" << REF_TYPE_LENGTH << "\n" - << " DataSectionOffset=" << DataSectionOffset - << " PtrSecIndex=" << SInfo.PtrSecIndex - << " patch loc="<< EachPatch.LocInByte << "\n"); - SInfo.SecBuf.replace(EachPatch.LocInByte, REF_TYPE_LENGTH * 4, UnsignedIntTypeToHex( - ReverseBytes(CreateRefContent(DataSectionIndex, DataSectionOffset), REF_TYPE_LENGTH), REF_TYPE_HEX_LENGTH)); + 8),8*2).c_str() + << " size=" << 8 << "\n"); + SInfo.SecBuf += UnsignedIntTypeToHex( + ReverseBytes(CreateRefContent(DataSectionIndex, DataSectionOffset), 8), 16); } } } @@ -422,10 +407,9 @@ void XVMAsmPrinter::InitGlobalConstantDataSequential( LLVM_DEBUG(dbgs() << "Add to Buf: " << UnsignedIntTypeToHex(ReverseBytes( CDS->getElementAsInteger(I), - ElementByteSize), ElementByteSize*CHAT_LEN_IN_HEX).c_str() + ElementByteSize), ElementByteSize*2).c_str() << " size=" << ElementByteSize << "\n"); - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(CDS->getElementAsInteger(I), ElementByteSize), - ElementByteSize*CHAT_LEN_IN_HEX); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(CDS->getElementAsInteger(I), ElementByteSize), ElementByteSize*2); } } else { llvm_unreachable("Should not have FP in sequential data"); @@ -437,25 +421,25 @@ void XVMAsmPrinter::InitGlobalConstantDataSequential( if (unsigned Padding = Size - EmittedSize) { LLVM_DEBUG(dbgs() << "\n------------Seq PADSIZE----------- " << Padding << "\n"); LLVM_DEBUG(dbgs() << "Add to Buf: " - << UnsignedIntTypeToHex(ReverseBytes(0, Padding), Padding*CHAT_LEN_IN_HEX).c_str() + << UnsignedIntTypeToHex(ReverseBytes(0, Padding), Padding*2).c_str() << " size=" << Padding << "\n"); - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, Padding), Padding*CHAT_LEN_IN_HEX); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, Padding), Padding*2); } } void XVMAsmPrinter::InitGlobalConstantArray(const DataLayout &DL, const ConstantArray *CA, const Constant *BaseCV, uint64_t Offset, - XVMSectionInfo* SInfo, Module *M) { + XVMSectionInfo* SInfo) { LLVM_DEBUG(dbgs() << "\n--------------------InitGlobalConstantArray-------------------\n"); for (unsigned I = 0, E = CA->getNumOperands(); I != E; ++I) { - InitGlobalConstantImpl(DL, CA->getOperand(I), BaseCV, Offset, SInfo, M); - Offset += DL.getTypeAllocSize(CA->getOperand(I)->getType()); + InitGlobalConstantImpl(DL, CA->getOperand(I), BaseCV, Offset, SInfo); + Offset += DL.getTypeAllocSize(CA->getOperand(I)->getType()); } } void XVMAsmPrinter::InitGlobalConstantStruct(const DataLayout &DL, const ConstantStruct *CS, const Constant *BaseCV, uint64_t Offset, - XVMSectionInfo* SInfo, Module *M) { + XVMSectionInfo* SInfo) { LLVM_DEBUG(dbgs() << "\n--------------------InitGlobalConstantStruct-------------------\n"); unsigned Size = DL.getTypeAllocSize(CS->getType()); const StructLayout *Layout = DL.getStructLayout(CS->getType()); @@ -464,7 +448,7 @@ void XVMAsmPrinter::InitGlobalConstantStruct(const DataLayout &DL, const Constan const Constant *Field = CS->getOperand(I); // Print the actual field value. - InitGlobalConstantImpl(DL, Field, BaseCV, Offset + SizeSoFar, SInfo, M); + InitGlobalConstantImpl(DL, Field, BaseCV, Offset + SizeSoFar, SInfo); // Check if padding is needed and insert one or more 0s. uint64_t FieldSize = DL.getTypeAllocSize(Field->getType()); @@ -477,9 +461,9 @@ void XVMAsmPrinter::InitGlobalConstantStruct(const DataLayout &DL, const Constan if (PadSize > 0) { LLVM_DEBUG(dbgs() << "\n------------Struct PADSIZE-----------" << PadSize << "\n"); LLVM_DEBUG(dbgs() << "Add to Buf: " - << UnsignedIntTypeToHex(ReverseBytes(0, PadSize), PadSize*CHAT_LEN_IN_HEX).c_str() + << UnsignedIntTypeToHex(ReverseBytes(0, PadSize), PadSize*2).c_str() << " size=" << PadSize << "\n"); - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, PadSize), PadSize*CHAT_LEN_IN_HEX); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, PadSize), PadSize*2); } SizeSoFar += FieldSize + PadSize; } @@ -490,7 +474,7 @@ void XVMAsmPrinter::InitGlobalConstantStruct(const DataLayout &DL, const Constan void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, const Constant *BaseCV, uint64_t Offset, - XVMSectionInfo* SInfo, Module *M) { + XVMSectionInfo* SInfo) { LLVM_DEBUG(dbgs() << "\n--------------------InitGlobalConstantImpl " << CV->getName().str().c_str() << "-------------------\n"); @@ -505,7 +489,6 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant if (isa(CV) || isa(CV)) { if (SInfo->BufType == XVM_SECTION_DATA_TYPE_UNKNOWN) { SInfo->BufType = XVM_SECTION_DATA_TYPE_BSS; - SInfo->SecSize = Size; LLVM_DEBUG(dbgs() << "\nemit in InitGlobalConstantImpl bss " << Size << " " << DL.getTypeStoreSize(CV->getType()) << " " @@ -517,36 +500,23 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant << DL.getTypeStoreSize(CV->getType()) << " " << DL.getTypeAllocSize(CV->getType()).getFixedSize() << "\n"); LLVM_DEBUG(dbgs() << "Add to Buf: " - << UnsignedIntTypeToHex(ReverseBytes(0, Size), Size*CHAT_LEN_IN_HEX).c_str() + << UnsignedIntTypeToHex(ReverseBytes(0, Size), Size*2).c_str() << " size=" << Size << "\n"); - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, Size), Size*CHAT_LEN_IN_HEX); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, Size), Size*2); return; } if (const ConstantInt *CI = dyn_cast(CV)) { const uint64_t StoreSize = DL.getTypeStoreSize(CV->getType()); - if (StoreSize <= MAX_PTR_SIZE) { + if (StoreSize <= 8) { SInfo->BufType = SInfo->BufType | XVM_SECTION_DATA_TYPE_NUMERIC; LLVM_DEBUG(dbgs() << "\nemit in InitGlobalConstantImpl int\n"); LLVM_DEBUG(dbgs() << "Add to Buf: " - << UnsignedIntTypeToHex(ReverseBytes(CI->getZExtValue(), StoreSize), - StoreSize*CHAT_LEN_IN_HEX).c_str() + << UnsignedIntTypeToHex(ReverseBytes(CI->getZExtValue(), StoreSize), StoreSize*2).c_str() << " size=" << StoreSize << "\n"); - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(CI->getZExtValue(), StoreSize), StoreSize*CHAT_LEN_IN_HEX); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(CI->getZExtValue(), StoreSize), StoreSize*2); } else { - for (Function &F1 : M->getFunctionList()) { - for (BasicBlock &BB : F1) { - for (Instruction &I : BB) { - DebugLoc DL = I.getDebugLoc(); - ExportFailMsg(F1, DL, "Error: Large int globals are unsupported", (void*)&StoreSize); - LLVM_DEBUG(dbgs() << "XVM Error: Should not have large int global value!"); - exit(1); - break; - } - break; - } - break; - } + llvm_unreachable("Should not have large int global value!"); } return; } @@ -558,7 +528,7 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant SInfo->BufType = SInfo->BufType | XVM_SECTION_DATA_TYPE_POINTER; LLVM_DEBUG(dbgs() << "\nemit in InitGlobalConstantImpl nullptr\n"); LLVM_DEBUG(dbgs() << "Add to Buf: \\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" - << " size=" << MAX_PTR_SIZE << "\n"); + << " size=" << 8 << "\n"); SInfo->SecBuf += "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"; return; } @@ -566,25 +536,25 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant if (const ConstantDataSequential *CDS = dyn_cast(CV)) { SInfo->BufType = SInfo->BufType | XVM_SECTION_DATA_TYPE_STRING; return InitGlobalConstantDataSequential(DL, CDS, SInfo); - } + } if (const ConstantArray *CVA = dyn_cast(CV)) { SInfo->BufType = SInfo->BufType | XVM_SECTION_DATA_TYPE_ARRAY; - return InitGlobalConstantArray(DL, CVA, BaseCV, Offset, SInfo, M); + return InitGlobalConstantArray(DL, CVA, BaseCV, Offset, SInfo); } if (const ConstantStruct *CVS = dyn_cast(CV)) { SInfo->BufType = SInfo->BufType | XVM_SECTION_DATA_TYPE_STRUCT; - return InitGlobalConstantStruct(DL, CVS, BaseCV, Offset, SInfo, M); + return InitGlobalConstantStruct(DL, CVS, BaseCV, Offset, SInfo); } if (const ConstantExpr *CE = dyn_cast(CV)) { // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of // vectors). if (CE->getOpcode() == Instruction::BitCast) - return InitGlobalConstantImpl(DL, CE->getOperand(0), BaseCV, Offset, SInfo, M); + return InitGlobalConstantImpl(DL, CE->getOperand(0), BaseCV, Offset, SInfo); - if (Size > MAX_SIZE_CONSTANT_EXPRESSION) { + if (Size > 8) { // If the constant expression's size is greater than 64-bits, then we have // to emit the value in chunks. Try to constant fold the value and emit it // that way. @@ -595,16 +565,16 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant } if (const ConstantVector *V = dyn_cast(CV)) - llvm_unreachable("Should not have vector global value!"); + llvm_unreachable("Should not have vector global value!"); LLVM_DEBUG(dbgs() << "\nemit in InitGlobalConstantImpl ptr\n"); - int idx_func = GetFuncIndex(CV->getName().data()); + int idx_func = GetFuncIndex(CV->getName().data()); if (idx_func != -1) { SInfo->BufType = SInfo->BufType | XVM_SECTION_DATA_TYPE_POINTER; - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(idx_func, REF_TYPE_LENGTH), REF_TYPE_HEX_LENGTH); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(idx_func, 8), 16); LLVM_DEBUG(dbgs() << "\nsuccess in function pointer " - << UnsignedIntTypeToHex(ReverseBytes(idx_func, REF_TYPE_LENGTH), REF_TYPE_HEX_LENGTH).c_str() + << UnsignedIntTypeToHex(ReverseBytes(idx_func, 8), 16).c_str() << "\n"); return; } @@ -618,8 +588,6 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant PatchInfo.SymName = CV->getName().data(); PatchInfo.AddEnd = 0; - PatchInfo.LocInByte = SInfo->SecBuf.length(); - SInfo->SecBuf += "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"; SInfo->PatchListInfo.push_back(PatchInfo); return; } @@ -647,12 +615,9 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant PatchInfo.SymName = SymName; PatchInfo.AddEnd = (int)CE->getValue(); - // Please note that if the variable is defined after, then - // no DataSectionIndex - SInfo->BufType = XVM_SECTION_DATA_TYPE_POINTER; - PatchInfo.LocInByte = SInfo->SecBuf.length(); - SInfo->SecBuf += "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"; - SInfo->PatchListInfo.push_back(PatchInfo); + if (DataSectionIndex != -1) { + SInfo->BufType = XVM_SECTION_DATA_TYPE_POINTER; + } } else { SRE = dyn_cast(ME); @@ -664,23 +629,17 @@ void XVMAsmPrinter::InitGlobalConstantImpl(const DataLayout &DL, const Constant const auto &ConstA = cast(ME); const ConstantExpr *CExprA = dyn_cast(CV); assert(CExprA->getOpcode() == Instruction::IntToPtr); - PatchInfo.LocInByte = SInfo->SecBuf.length(); LLVM_DEBUG(dbgs() << "Add to Buf: " - << UnsignedIntTypeToHex(ReverseBytes(ConstA->getValue(), REF_TYPE_LENGTH), - REF_TYPE_HEX_LENGTH).c_str() - << " size=" << MAX_PTR_SIZE << "\n"); - SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(ConstA->getValue(), REF_TYPE_LENGTH), REF_TYPE_HEX_LENGTH); + << UnsignedIntTypeToHex(ReverseBytes(ConstA->getValue(), 8), 8*2).c_str() + << " size=" << 8 << "\n"); + SInfo->SecBuf += UnsignedIntTypeToHex(ReverseBytes(ConstA->getValue(), 8), 8*2); return; - } else if (ME->getKind() == llvm::MCExpr::SymbolRef) { - SInfo->BufType = XVM_SECTION_DATA_TYPE_POINTER; - PatchInfo.LocInByte = SInfo->SecBuf.length(); - SInfo->SecBuf += "\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00"; } rso << *ME; PatchInfo.SymName = StrME.data(); PatchInfo.AddEnd = 0; - SInfo->PatchListInfo.push_back(PatchInfo); } + SInfo->PatchListInfo.push_back(PatchInfo); return; } llvm_unreachable("unhandled global type!!"); @@ -718,16 +677,13 @@ void XVMAsmPrinter::InitDataSectionGlobalConstant(Module *M) { SInfo.SecBuf = ""; SInfo.SecComment = GV.getName().data(); SInfo.SymName = GV.getName().data(); - InitGlobalConstantImpl(DL, CV, nullptr, 0, &SInfo, M); + InitGlobalConstantImpl(DL, CV, nullptr, 0, &SInfo); } - LLVM_DEBUG(dbgs() << "buf size is " << Size << " buf=" - << SInfo.SecBuf.c_str() << "\n"); + LLVM_DEBUG(dbgs() << "buf is " + << SInfo.SecBuf.c_str() + << " size is " << Size << "\n"); // ser permission if (GV.isConstant()) { - if (SInfo.BufType == XVM_SECTION_DATA_TYPE_BSS) { - // zero init for constant should be in the ro with init - SInfo.SecBuf += UnsignedIntTypeToHex(ReverseBytes(0, SInfo.SecSize), SInfo.SecSize*2); - } SInfo.Permission = XVM_SECTION_PERM_RO; SInfo.SecName = "rodata"; } else { @@ -883,7 +839,7 @@ void XVMAsmPrinter::setFunctionCallInfo(MCInst *Inst) { void XVMAsmPrinter::setGlobalSymbolInfo(const MachineInstr *MI, MCInst* Inst) { unsigned int numOps = MI->getNumOperands(); bool hasGlobalSymbol = false; - for (unsigned int i = 0; i < numOps; i++) + for (unsigned int i=0; igetOperand(i); if (tmp.isGlobal()) { @@ -916,10 +872,8 @@ void XVMAsmPrinter::setGlobalSymbolInfo(const MachineInstr *MI, MCInst* Inst) { SymName = GetSymbolName(SymName); SymIndex = GetDataIndex(SymName.c_str(), DATA_SECTION); if (SymIndex == -1) { - const MachineFunction *F = MI->getParent()->getParent(); - ExportFailMsg(F->getFunction(), MI->getDebugLoc(), "Error: Externs aren't supported", NULL); - LLVM_DEBUG(dbgs() << "XVM TODO: Add the support of non-func-global-var scenarios\n"); - exit(1); + report_fatal_error( + "Note: Add the support of non-func-global-var scenarios\n"); } else { Inst->setFlags(GLOBAL_DATAREF_FLAG_MC_INST); MCOperand MCOp = MCOperand::createImm(SymIndex); @@ -948,7 +902,7 @@ void XVMAsmPrinter::emitInstruction(const MachineInstr *MI) { void XVMAsmPrinter::emitFunctionHeader() { const Function &F = MF->getFunction(); - SmallString Str; + SmallString<128> Str; raw_svector_ostream O(Str); int Index = GetDefFuncIndex(F.getName().data()); assert(Index != -1); @@ -984,17 +938,14 @@ void XVMAsmPrinter::emitFunctionReturnVal(const Function &F, raw_ostream &O) { } else if (Ty->isIntegerTy()) { O << " i64"; } else if (!Ty->isVoidTy()) { - DebugLoc DL; - ExportFailMsg(F, DL, "Invalid return type", NULL); - LLVM_DEBUG(dbgs() << "XVM Error: Invalid return type"); - exit(1); + llvm_unreachable("Invalid return type"); } O << ")"; } void XVMAsmPrinter::emitFunctionBodyEnd() { - SmallString Str; + SmallString<128> Str; raw_svector_ostream O(Str); O << "\t)"; if (MF->getFunction().hasFnAttribute("xvm-export-name")) @@ -1021,10 +972,7 @@ void XVMAsmPrinter::emitFunctionParamList(const Function &F, raw_ostream &O) { } else if (Ty->isIntegerTy()) { O << " i64"; } else { - DebugLoc DL; - ExportFailMsg(F, DL, "Invalid (non ref or interger) param type", NULL); - LLVM_DEBUG(dbgs() << "XVM Error: Invalid param type"); - exit(1); + llvm_unreachable("Invalid param type"); } } @@ -1034,7 +982,7 @@ void XVMAsmPrinter::emitFunctionParamList(const Function &F, raw_ostream &O) { void XVMAsmPrinter::emitStartOfAsmFile(Module &M) { InitModuleMapFuncnameIndex(&M); InitDataSectionGlobalConstant(&M); - SmallString Str1; + SmallString<128> Str1; raw_svector_ostream O(Str1); O << "(module"; @@ -1080,7 +1028,7 @@ static void emitConstructorsDestructors(raw_svector_ostream &O, Module &M, return; } StructType *ETy = dyn_cast(InitList->getType()->getElementType()); - if (!ETy || ETy->getNumElements() != NUM_MO_CTOR_DTOR || + if (!ETy || ETy->getNumElements() != 3 || !ETy->getTypeAtIndex(0U)->isIntegerTy() || !ETy->getTypeAtIndex(1U)->isPointerTy() || !ETy->getTypeAtIndex(2U)->isPointerTy()) { @@ -1111,7 +1059,7 @@ static void emitMetaDataSectionInfo(raw_svector_ostream &O, Module &M) { } void XVMAsmPrinter::emitEndOfAsmFile(Module &M) { - SmallString Str1; + SmallString<128> Str1; raw_svector_ostream O(Str1); emitDecls(M); emitDataSectionInfo(O); @@ -1121,7 +1069,7 @@ void XVMAsmPrinter::emitEndOfAsmFile(Module &M) { } void XVMAsmPrinter::emitDecls(const Module &M) { - SmallString Str1; + SmallString<128> Str1; raw_svector_ostream O(Str1); for (const Function &F : M.getFunctionList()) { if (GetDefFuncIndex(F.getName().data()) == -1 && @@ -1173,35 +1121,12 @@ void XVMAsmPrinter::GetMIIndent(MachineFunction &MF) { assert (CurrentIndent == 0 && "All the indents should be paired!"); } -static void checkFunctionSize(MachineFunction &MF) { - int count = 0; - - for (auto &MBB : MF) { - for (auto &MI : MBB) { - count++; - } - } - - if (count > MAX_FUNC_SIZE) { - DebugLoc DL; - Function &F = MF.getFunction(); - std::string ErrorMesg("Error: Function '"); - ErrorMesg += MF.getName().str().c_str(); - ErrorMesg += "' has "; - ErrorMesg += std::to_string(count); - ErrorMesg += " instructions. Max instructions is 32767.\n"; - ExportFailMsg(F, DL, ErrorMesg.data(), NULL); - exit(1); - } -} - void XVMAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {} bool XVMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SetupMachineFunction(MF); GetMIIndent(MF); emitFunctionBody(); - checkFunctionSize(MF); return false; } diff --git a/llvm/lib/Target/XVM/XVMCFGSort.cpp b/llvm/lib/Target/XVM/XVMCFGSort.cpp index 905277d5f8a8..d8e5d803d4e0 100644 --- a/llvm/lib/Target/XVM/XVMCFGSort.cpp +++ b/llvm/lib/Target/XVM/XVMCFGSort.cpp @@ -19,33 +19,35 @@ #include "MCTargetDesc/XVMMCTargetDesc.h" #include "XVM.h" -#include "llvm/CodeGen/MachineLoopInfo.h" #include "XVMSortRegion.h" -#include "llvm/CodeGen/MachineDominators.h" #include "XVMSubtarget.h" #include "llvm/ADT/PriorityQueue.h" - -#define DEBUG_TYPE "xvm-cfg-sort" -#define INIT_SMALL_VECTOR_PREDS_SIZE 16 -#define INIT_SMALL_VECTOR_ENTRIES_SIZE 4 - +#include "llvm/ADT/SetVector.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; using XVM::SortRegion; using XVM::SortRegionInfo; +#define DEBUG_TYPE "xvm-cfg-sort" + namespace { class XVMCFGSort final : public MachineFunctionPass { StringRef getPassName() const override { return "XVM CFG Sort"; } - void getAnalysisUsage(AnalysisUsage &AUsage) const override - { - AUsage.setPreservesCFG(); - AUsage.addRequired(); - AUsage.addPreserved(); - AUsage.addRequired(); - AUsage.addPreserved(); - MachineFunctionPass::getAnalysisUsage(AUsage); + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + MachineFunctionPass::getAnalysisUsage(AU); } bool runOnMachineFunction(MachineFunction &MF) override; @@ -64,220 +66,231 @@ FunctionPass *llvm::createXVMCFGSort() { return new XVMCFGSort(); } -static void maybeUpdateTerminator(MachineBasicBlock *MBBlock) { +static void maybeUpdateTerminator(MachineBasicBlock *MBB) { #ifndef NDEBUG - bool Barrier = false; + bool AnyBarrier = false; #endif - bool Analyzable = true; - for (const MachineInstr &TermIter : MBBlock->terminators()) { + bool AllAnalyzable = true; + for (const MachineInstr &Term : MBB->terminators()) { #ifndef NDEBUG - Barrier |= TermIter.isBarrier(); + AnyBarrier |= Term.isBarrier(); #endif - Analyzable &= TermIter.isBranch() && !TermIter.isIndirectBranch(); + AllAnalyzable &= Term.isBranch() && !Term.isIndirectBranch(); } - assert((Barrier || Analyzable) && "all fallthrough blocks are processed by analyzeBranch"); + assert((AnyBarrier || AllAnalyzable) && + "analyzeBranch needs to analyze any block with a fallthrough"); - // Using the original block order find the layotu successor - MachineFunction *MFunction = MBBlock->getParent(); - MachineBasicBlock *OriginalNext = - unsigned(MBBlock->getNumber() + 1) < MFunction->getNumBlockIDs() - ? MFunction->getBlockNumbered(MBBlock->getNumber() + 1) : nullptr; + // Find the layout successor from the original block order. + MachineFunction *MF = MBB->getParent(); + MachineBasicBlock *OriginalSuccessor = + unsigned(MBB->getNumber() + 1) < MF->getNumBlockIDs() + ? MF->getBlockNumbered(MBB->getNumber() + 1) + : nullptr; - if (Analyzable) - MBBlock->updateTerminator(OriginalNext); + if (AllAnalyzable) + MBB->updateTerminator(OriginalSuccessor); } -/// Reverse Block sorting based on their number. -struct CompareBlockNumbersBackwards { - bool operator()(const MachineBasicBlock *First, - const MachineBasicBlock *Second) const { - return First->getNumber() < Second->getNumber(); - } -}; - namespace { -/// Block sorting based on their number. +/// Sort blocks by their number. struct CompareBlockNumbers { - bool operator()(const MachineBasicBlock *First, - const MachineBasicBlock *Second) const { - return First->getNumber() > Second->getNumber(); + bool operator()(const MachineBasicBlock *A, + const MachineBasicBlock *B) const { + return A->getNumber() > B->getNumber(); } }; - -// So we don't mix blocks not dominated by its header -// amond its blocks we use bookkeeping +/// Sort blocks by their number in the opposite order.. +struct CompareBlockNumbersBackwards { + bool operator()(const MachineBasicBlock *A, + const MachineBasicBlock *B) const { + return A->getNumber() < B->getNumber(); + } +}; +/// Bookkeeping for a region to help ensure that we don't mix blocks not +/// dominated by the its header among its blocks. struct Entry { - const SortRegion *Region; - unsigned BlocksLeftCount; + const SortRegion *TheRegion; + unsigned NumBlocksLeft; - // A List of blocks not dominated by Loop's header that - // are deferred until after all of the Loop's blocks have been seen. - std::vector Def; + /// List of blocks not dominated by Loop's header that are deferred until + /// after all of Loop's blocks have been seen. + std::vector Deferred; - explicit Entry(const SortRegion *SR) : Region(SR), BlocksLeftCount(SR->getNumBlocks()) {} + explicit Entry(const SortRegion *R) + : TheRegion(R), NumBlocksLeft(R->getNumBlocks()) {} }; -} // anonymous namespace end +} // end anonymous namespace -// Making sure that regions are not inerrupted by blocks not -// dominated by their header sort the blocks +/// Sort the blocks, taking special care to make sure that regions are not +/// interrupted by blocks not dominated by their header. /// Note: There are many opportunities for improving the heuristics here. /// Explore them. -static void sortBlocks(MachineFunction &MFunction, const MachineLoopInfo &MLInfo, - const MachineDominatorTree &MDTree) { - // So we can update terminators after reordering to point to the - // original layout successor, remember original layout - MFunction.RenumberBlocks(); +static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI, + const MachineDominatorTree &MDT) { + // Remember original layout ordering, so we can update terminators after + // reordering to point to the original layout successor. + MF.RenumberBlocks(); - // Record the number of predecessors each block has, ignoring loop backedges, - // to prepare for a topological sort - SmallVector NumPredsLeft(MFunction.getNumBlockIDs(), 0); - for (MachineBasicBlock &MBBlock : MFunction) { - unsigned Size = MBBlock.pred_size(); - if (MachineLoop *Loop = MLInfo.getLoopFor(&MBBlock)) - if (Loop->getHeader() == &MBBlock) - for (const MachineBasicBlock *Prev : MBBlock.predecessors()) - if (Loop->contains(Prev)) - --Size; - NumPredsLeft[MBBlock.getNumber()] = Size; + // Prepare for a topological sort: Record the number of predecessors each + // block has, ignoring loop backedges. + SmallVector NumPredsLeft(MF.getNumBlockIDs(), 0); + for (MachineBasicBlock &MBB : MF) { + unsigned N = MBB.pred_size(); + if (MachineLoop *L = MLI.getLoopFor(&MBB)) + if (L->getHeader() == &MBB) + for (const MachineBasicBlock *Pred : MBB.predecessors()) + if (L->contains(Pred)) + --N; + NumPredsLeft[MBB.getNumber()] = N; } - // Topological sort, but between a region header and the last block in - // the region, there can be no block not dominated by its header. - // AS well its desirable to preserve the original block order of possible - // Perfer has revenetly processed successors to help keep block order - // BlockReady has the remaining blocks - PriorityQueue, CompareBlockNumbers> - Prefer; - PriorityQueue, CompareBlockNumbersBackwards> - BlockReady; - SortRegionInfo SRI(MLInfo); - SmallVector SEntries; - for (MachineBasicBlock *MBBlock = &MFunction.front();;) { - const SortRegion *SR = SRI.getRegionFor(MBBlock); - if (SR) { - // Can't put any blocks that it doesnt dominate until we see the end - // of the region if MBBlock is a header - if (SR->getHeader() == MBBlock) - SEntries.push_back(Entry(SR)); - // Decrement the count for each active region the block is a part of - // Take any MBBlock that is the last block in an active region off the list - // picking up any blocks deferred, since the header didnt dominate them. - for (Entry &Ent : SEntries) - if (Ent.Region->contains(MBBlock) && --Ent.BlocksLeftCount == 0) - for (auto DBlock : Ent.Def) - BlockReady.push(DBlock); - while (!SEntries.empty() && SEntries.back().BlocksLeftCount == 0) - SEntries.pop_back(); + // Topological sort the CFG, with additional constraints: + // - Between a region header and the last block in the region, there can be + // no blocks not dominated by its header. + // - It's desirable to preserve the original block order when possible. + // We use two ready lists; Preferred and Ready. Preferred has recently + // processed successors, to help preserve block sequences from the original + // order. Ready has the remaining ready blocks. + PriorityQueue, + CompareBlockNumbers> + Preferred; + PriorityQueue, + CompareBlockNumbersBackwards> + Ready; + + SortRegionInfo SRI(MLI); + SmallVector Entries; + for (MachineBasicBlock *MBB = &MF.front();;) { + const SortRegion *R = SRI.getRegionFor(MBB); + if (R) { + // If MBB is a region header, add it to the active region list. We can't + // put any blocks that it doesn't dominate until we see the end of the + // region. + if (R->getHeader() == MBB) + Entries.push_back(Entry(R)); + // For each active region the block is in, decrement the count. If MBB is + // the last block in an active region, take it off the list and pick up + // any blocks deferred because the header didn't dominate them. + for (Entry &E : Entries) + if (E.TheRegion->contains(MBB) && --E.NumBlocksLeft == 0) + for (auto DeferredBlock : E.Deferred) + Ready.push(DeferredBlock); + while (!Entries.empty() && Entries.back().NumBlocksLeft == 0) + Entries.pop_back(); } - for (MachineBasicBlock *Next : MBBlock->successors()) { // Topological sort logic. - if (MachineLoop *NextL = MLInfo.getLoopFor(Next)) // Backedges can be ignored. - if (NextL->getHeader() == Next && NextL->contains(MBBlock)) + // The main topological sort logic. + for (MachineBasicBlock *Succ : MBB->successors()) { + // Ignore backedges. + if (MachineLoop *SuccL = MLI.getLoopFor(Succ)) + if (SuccL->getHeader() == Succ && SuccL->contains(MBB)) continue; - // Decrement how many are left. It's ready if its now 0. - if (--NumPredsLeft[Next->getNumber()] == 0) { - // We allow soritng of BBs that belong to the current region, and also - // BB's that are dominated bu the current region, when we are in a SortRegion - Prefer.push(Next); + // Decrement the predecessor count. If it's now zero, it's ready. + if (--NumPredsLeft[Succ->getNumber()] == 0) { + // When we are in a SortRegion, we allow sorting of not only BBs that + // belong to the current (innermost) region but also BBs that are + // dominated by the current region header. + Preferred.push(Succ); } } - // To find the block to follow MBBlock, try to find a preferred block to - // save the orinal block order if permitted - MachineBasicBlock *Successor = nullptr; - while (!Prefer.empty()) { - Successor = Prefer.top(); - Prefer.pop(); - // until the region is done, keep defering X until it is dominated - // by the top active region - if (!SEntries.empty() && - !MDTree.dominates(SEntries.back().Region->getHeader(), Successor)) { - SEntries.back().Def.push_back(Successor); - Successor = nullptr; + // Determine the block to follow MBB. First try to find a preferred block, + // to preserve the original block order when possible. + MachineBasicBlock *Next = nullptr; + while (!Preferred.empty()) { + Next = Preferred.top(); + Preferred.pop(); + // If X isn't dominated by the top active region header, defer it until + // that region is done. + if (!Entries.empty() && + !MDT.dominates(Entries.back().TheRegion->getHeader(), Next)) { + Entries.back().Deferred.push_back(Next); + Next = nullptr; continue; } - // Succcessor is not preferred ig it was originally ordered before MBBlock - // and that wasnt caused by it being loop-rotated above the header - if (Successor->getNumber() < MBBlock->getNumber() && - (!SR || !SR->contains(Successor) || - SR->getHeader()->getNumber() < Successor->getNumber())) { - BlockReady.push(Successor); - Successor = nullptr; + // If Next was originally ordered before MBB, and it isn't because it was + // loop-rotated above the header, it's not preferred. + if (Next->getNumber() < MBB->getNumber() && + (!R || !R->contains(Next) || + R->getHeader()->getNumber() < Next->getNumber())) { + Ready.push(Next); + Next = nullptr; continue; } break; } - // Check the general Ready list, if we did't find suitable block in - // in the prefer list - if (!Successor) { - // We are done if ther are no more blocks to process - if (BlockReady.empty()) { - maybeUpdateTerminator(MBBlock); + // If we didn't find a suitable block in the Preferred list, check the + // general Ready list. + if (!Next) { + // If there are no more blocks to process, we're done. + if (Ready.empty()) { + maybeUpdateTerminator(MBB); break; } for (;;) { - Successor = BlockReady.top(); - BlockReady.pop(); - // Unitl the region is done, keep defering Successor if it - // isnt dominated by the top active region header - if (!SEntries.empty() && - !MDTree.dominates(SEntries.back().Region->getHeader(), Successor)) { - SEntries.back().Def.push_back(Successor); + Next = Ready.top(); + Ready.pop(); + // If Next isn't dominated by the top active region header, defer it + // until that region is done. + if (!Entries.empty() && + !MDT.dominates(Entries.back().TheRegion->getHeader(), Next)) { + Entries.back().Deferred.push_back(Next); continue; } break; } } - // Iterate and move the Successor block into place. - Successor->moveAfter(MBBlock); - maybeUpdateTerminator(MBBlock); - MBBlock = Successor; + // Move the next block into place and iterate. + Next->moveAfter(MBB); + maybeUpdateTerminator(MBB); + MBB = Next; } - assert(SEntries.empty() && "Have to finish Active sort region"); - MFunction.RenumberBlocks(); + assert(Entries.empty() && "Active sort region list not finished"); + MF.RenumberBlocks(); #ifndef NDEBUG - SmallSetVector OnS; + SmallSetVector OnStack; - // Representing the degenerate loop that starts at the function entry, - // and includes the entire function as a loop that executes one, - // insert a sentinel - OnS.insert(nullptr); + // Insert a sentinel representing the degenerate loop that starts at the + // function entry block and includes the entire function as a "loop" that + // executes once. + OnStack.insert(nullptr); - for (auto &MBBlock : MFunction) { - assert(MBBlock.getNumber() >= 0 && "Renumbered block is not non-negative."); - const SortRegion *SRegion = SRI.getRegionFor(&MBBlock); + for (auto &MBB : MF) { + assert(MBB.getNumber() >= 0 && "Renumbered blocks should be non-negative."); + const SortRegion *Region = SRI.getRegionFor(&MBB); - if (SRegion && &MBBlock == SRegion->getHeader()) { // Region header. - if (SRegion->isLoop()) { - // Loop header, one predecossor should be backedges bellow, - // and the other should have been processed above - for (auto Prev : MBBlock.predecessors()) + if (Region && &MBB == Region->getHeader()) { + // Region header. + if (Region->isLoop()) { + // Loop header. The loop predecessor should be sorted above, and the + // other predecessors should be backedges below. + for (auto Pred : MBB.predecessors()) assert( - (Prev->getNumber() < MBBlock.getNumber() || SRegion->contains(Prev)) && - "Loop header predecessors have to be loop backedges or " - "predecessors"); + (Pred->getNumber() < MBB.getNumber() || Region->contains(Pred)) && + "Loop header predecessors must be loop predecessors or " + "backedges"); } else { - // All predecessors should have all been sorted above. Exception header. - for (auto Prev : MBBlock.predecessors()) - assert(Prev->getNumber() < MBBlock.getNumber() && - "Non-loop-header predecessors have to be topologically sorted"); + // Exception header. All predecessors should be sorted above. + for (auto Pred : MBB.predecessors()) + assert(Pred->getNumber() < MBB.getNumber() && + "Non-loop-header predecessors should be topologically sorted"); } - assert(OnS.insert(SRegion) && - "Can't declare regions more than once."); + assert(OnStack.insert(Region) && + "Regions should be declared at most once."); } else { - // Predecessors should have all beeen sorted above. Not region header. - for (auto Prev : MBBlock.predecessors()) - assert(Prev->getNumber() < MBBlock.getNumber() && - "Non-loop-header predecessors are not topologically sorted"); - assert(OnS.count(SRI.getRegionFor(&MBBlock)) && - "Blocks are not nested in their regions"); + // Not a region header. All predecessors should be sorted above. + for (auto Pred : MBB.predecessors()) + assert(Pred->getNumber() < MBB.getNumber() && + "Non-loop-header predecessors should be topologically sorted"); + assert(OnStack.count(SRI.getRegionFor(&MBB)) && + "Blocks must be nested in their regions"); } - while (OnS.size() > 1 && &MBBlock == SRI.getBottom(OnS.back())) - OnS.pop_back(); + while (OnStack.size() > 1 && &MBB == SRI.getBottom(OnStack.back())) + OnStack.pop_back(); } - assert(OnS.pop_back_val() == nullptr && - "A region header can't be the function entry block"); - assert(OnS.empty() && - "Control flow stack pops and stack pushes should be balanced."); + assert(OnStack.pop_back_val() == nullptr && + "The function entry block shouldn't actually be a region header"); + assert(OnStack.empty() && + "Control flow stack pushes and pops should be balanced."); #endif } @@ -297,4 +310,4 @@ bool XVMCFGSort::runOnMachineFunction(MachineFunction &MF) { return true; } -#endif +#endif \ No newline at end of file diff --git a/llvm/lib/Target/XVM/XVMCFGStackify.cpp b/llvm/lib/Target/XVM/XVMCFGStackify.cpp index ad5d438fd01b..6215156e3947 100644 --- a/llvm/lib/Target/XVM/XVMCFGStackify.cpp +++ b/llvm/lib/Target/XVM/XVMCFGStackify.cpp @@ -22,6 +22,7 @@ //===----------------------------------------------------------------------===// #ifdef XVM_DYLIB_MODE + #include "XVM.h" #include "XVMSortRegion.h" #include "XVMSubtarget.h" @@ -36,8 +37,9 @@ using namespace llvm; using XVM::SortRegionInfo; #define DEBUG_TYPE "xvm-cfg-stackify" -#define INIT_SMALL_VECTOR_SCOPESS_SIZE 8 -#define INIT_SMALL_VECTOR_MO_SIZE 4 + +STATISTIC(NumCallUnwindMismatches, "Number of call unwind mismatches found"); +STATISTIC(NumCatchUnwindMismatches, "Number of catch unwind mismatches found"); namespace { class XVMCFGStackify final : public MachineFunctionPass { @@ -55,17 +57,17 @@ class XVMCFGStackify final : public MachineFunctionPass { // For each block whose label represents the end of a scope, record the block // which holds the beginning of the scope. This will allow us to quickly skip // over scoped regions when walking blocks. - SmallVector ScopeTops; - void updateScopeTops(MachineBasicBlock *Start, MachineBasicBlock *Finish) { - int FinishNo = Finish->getNumber(); - if (!ScopeTops[FinishNo] || ScopeTops[FinishNo]->getNumber() > Start->getNumber()) - ScopeTops[FinishNo] = Start; + SmallVector ScopeTops; + void updateScopeTops(MachineBasicBlock *Begin, MachineBasicBlock *End) { + int EndNo = End->getNumber(); + if (!ScopeTops[EndNo] || ScopeTops[EndNo]->getNumber() > Begin->getNumber()) + ScopeTops[EndNo] = Begin; } // Placing markers. - void placeMarkers(MachineFunction &MFunction); - void placeBlockMarker(MachineBasicBlock &MBBlock); - void placeLoopMarker(MachineBasicBlock &MBBlock); + void placeMarkers(MachineFunction &MF); + void placeBlockMarker(MachineBasicBlock &MBB); + void placeLoopMarker(MachineBasicBlock &MBB); const XVMInstrInfo *TII = nullptr; void extendCondStmt(std::map CondBranchsWithDepth, MachineFunction &MF); @@ -81,49 +83,52 @@ class XVMCFGStackify final : public MachineFunctionPass { const MachineBasicBlock *MBB); void rewriteDepthImmediates(MachineFunction &MF); void fixBackEdgesOfLoops(MachineFunction &MF); - void fixEndsAtEndOfFunction(MachineFunction &MFunction); - void cleanupFunctionData(MachineFunction &MFunction); + void fixEndsAtEndOfFunction(MachineFunction &MF); + void cleanupFunctionData(MachineFunction &MF); - // The correspinding BLOCK|LOOP|TRY for each END_(BLOCK|LOOP|TRY) - DenseMap EndToBegin; - // The corresponding END_(BLOCK|LOOP|TRY) or DELEGATE for each BLOCK|LOOP|TRY - // (in the TRY case). + // For each BLOCK|LOOP|TRY, the corresponding END_(BLOCK|LOOP|TRY) or DELEGATE + // (in case of TRY). DenseMap BeginToEnd; + // For each END_(BLOCK|LOOP|TRY) or DELEGATE, the corresponding + // BLOCK|LOOP|TRY. + DenseMap EndToBegin; // We need an appendix block to place 'end_loop' or 'end_try' marker when the // loop / exception bottom block is the last block in a function - MachineBasicBlock *AppendixBBlock = nullptr; - MachineBasicBlock *getAppendixBlock(MachineFunction &MFunction){ - AppendixBBlock = nullptr; - if (!AppendixBBlock) { - AppendixBBlock = MFunction.CreateMachineBasicBlock(); - // For AsmPrinter to prints its label, we give it a fake predecessor - AppendixBBlock->addSuccessor(AppendixBBlock); - MFunction.push_back(AppendixBBlock); + MachineBasicBlock *AppendixBB = nullptr; + MachineBasicBlock *getAppendixBlock(MachineFunction &MF) { + AppendixBB = nullptr; + if (!AppendixBB) { + AppendixBB = MF.CreateMachineBasicBlock(); + // Give it a fake predecessor so that AsmPrinter prints its label. + AppendixBB->addSuccessor(AppendixBB); + MF.push_back(AppendixBB); } - return AppendixBBlock; + return AppendixBB; } - // "delegate" has a BB as its destincation operand, before running - // rewriteDEpthImmediated. Use a fake BB for the operand when "delegate" - // needs to rethrow to the caller, returned by getFakeCallerBlock. The - // number of block depths + 1 will be rewritten as an immediate value in - // rewriteDepthImmediates, and this fake BB will be removed at the end - MachineBasicBlock *FakeBBlockCaller = nullptr; - MachineBasicBlock *getFakeCallerBlock(MachineFunction &MFunction) { - if (!FakeBBlockCaller) - FakeBBlockCaller = MFunction.CreateMachineBasicBlock(); - return FakeBBlockCaller; + // Before running rewriteDepthImmediates function, 'delegate' has a BB as its + // destination operand. getFakeCallerBlock() returns a fake BB that will be + // used for the operand when 'delegate' needs to rethrow to the caller. This + // will be rewritten as an immediate value that is the number of block depths + // + 1 in rewriteDepthImmediates, and this fake BB will be removed at the end + // of the pass. + MachineBasicBlock *FakeCallerBB = nullptr; + MachineBasicBlock *getFakeCallerBlock(MachineFunction &MF) { + if (!FakeCallerBB) + FakeCallerBB = MF.CreateMachineBasicBlock(); + return FakeCallerBB; } - //marker instructions created function to register/unregister scope info - void registerScope(MachineInstr *Start, MachineInstr *Finish); - void registerTryScope(MachineInstr *Start, - MachineInstr *Finish, MachineBasicBlock *EHPad); - void unregisterScope(MachineInstr *Start); + // Helper functions to register / unregister scope information created by + // marker instructions. + void registerScope(MachineInstr *Begin, MachineInstr *End); + void registerTryScope(MachineInstr *Begin, MachineInstr *End, + MachineBasicBlock *EHPad); + void unregisterScope(MachineInstr *Begin); public: - static char ID; // typeid replacement, for identification + static char ID; // Pass identification, replacement for typeid XVMCFGStackify() : MachineFunctionPass(ID) {} ~XVMCFGStackify() override { releaseMemory(); } void releaseMemory() override; @@ -139,64 +144,66 @@ FunctionPass *llvm::createXVMCFGStackify() { return new XVMCFGStackify(); } - -// As opposed to falling through, test whether Pre has any terminators -// explicitly branching to MBB. Note: We check to see if therey are any explicit -// mentions of a branch instruction both branching to and falling through -// to a block through the actual branch operands (e.g. unoptimzed code) -static bool explicitlyBranchesTo(MachineBasicBlock *Pre, MachineBasicBlock *MBBlock) { - bool ret = false; - for (MachineInstr &MInst : Pre->terminators()) - for (MachineOperand &MOp : MInst.explicit_operands()) - if (MOp.isMBB() && MOp.getMBB() == MBBlock) - ret = true; - return ret; +/// Test whether Pred has any terminators explicitly branching to MBB, as +/// opposed to falling through. Note that it's possible (eg. in unoptimized +/// code) for a branch instruction to both branch to a block and fallthrough +/// to it, so we check the actual branch operands to see if there are any +/// explicit mentions. +static bool explicitlyBranchesTo(MachineBasicBlock *Pred, + MachineBasicBlock *MBB) { + for (MachineInstr &MI : Pred->terminators()) + for (MachineOperand &MO : MI.explicit_operands()) + if (MO.isMBB() && MO.getMBB() == MBB) + return true; + return false; } -// Satisfying the restriction set by Before and After; returns -// an iterator to the earliet position possible withtin the MBBlock -// Before and After hold the instructions that should go -// before and after the set respectivley. In this case After is -// only used for validation checking +// Returns an iterator to the earliest position possible within the MBB, +// satisfying the restrictions given by BeforeSet and AfterSet. BeforeSet +// contains instructions that should go before the marker, and AfterSet contains +// ones that should go after the marker. In this function, AfterSet is only +// used for validation checking. template -static MachineBasicBlock::iterator getEarliestInsertPos(MachineBasicBlock *MBBlock, - const Container &Before, - const Container &After) { - auto InsertPosition = MBBlock->end(); - while (InsertPosition != MBBlock->begin()) { - if (Before.count(&*std::prev(InsertPosition))) { -#ifndef NDEBUG // Validation check - for (auto Position = InsertPosition, E = MBBlock->begin(); Position != E; --Position) - assert(!After.count(&*std::prev(Position))); +static MachineBasicBlock::iterator +getEarliestInsertPos(MachineBasicBlock *MBB, const Container &BeforeSet, + const Container &AfterSet) { + auto InsertPos = MBB->end(); + while (InsertPos != MBB->begin()) { + if (BeforeSet.count(&*std::prev(InsertPos))) { +#ifndef NDEBUG + // Validation check + for (auto Pos = InsertPos, E = MBB->begin(); Pos != E; --Pos) + assert(!AfterSet.count(&*std::prev(Pos))); #endif break; } - --InsertPosition; + --InsertPos; } - return InsertPosition; + return InsertPos; } -// Satisfying the restriction set by Before and After; returns -// an iterator to the earliet position possible withtin the MBBlock -// Before and After hold the instructions that should go -// before and after the set respectivley. In this case Before is -// only used for validation checking +// Returns an iterator to the latest position possible within the MBB, +// satisfying the restrictions given by BeforeSet and AfterSet. BeforeSet +// contains instructions that should go before the marker, and AfterSet contains +// ones that should go after the marker. In this function, BeforeSet is only +// used for validation checking. template -static MachineBasicBlock::iterator getLatestInsertPos(MachineBasicBlock *MBBlock, - const Container &Before, - const Container &After) { - auto InsertPosition = MBBlock->begin(); - while (InsertPosition != MBBlock->end()) { - if (After.count(&*InsertPosition)) { -#ifndef NDEBUG // Validation check - for (auto Position = InsertPosition, E = MBBlock->end(); Position != E; ++Position) - assert(!Before.count(&*Position)); +static MachineBasicBlock::iterator +getLatestInsertPos(MachineBasicBlock *MBB, const Container &BeforeSet, + const Container &AfterSet) { + auto InsertPos = MBB->begin(); + while (InsertPos != MBB->end()) { + if (AfterSet.count(&*InsertPos)) { +#ifndef NDEBUG + // Validation check + for (auto Pos = InsertPos, E = MBB->end(); Pos != E; ++Pos) + assert(!BeforeSet.count(&*Pos)); #endif break; } - ++InsertPosition; + ++InsertPos; } - return InsertPosition; + return InsertPos; } void ChangeBranchCondOpc(MachineInstr &MI, const XVMInstrInfo *TII) { @@ -248,70 +255,21 @@ void XVMCFGStackify::fixBackEdgesOfLoops(MachineFunction &MF) { MI.eraseFromParent(); break; } else if (TII->isCondBranch(&MI) && MI.getOperand(0).getMBB() == LoopHeader) { - uint32_t action_opcode = XVM::CONTINUE; - /* Fix Loop Exiting Fallthrough */ - if (&MBB == Loop->getBottomBlock() && - &MI == &*(--MBB.end()) && - MLI.getLoopFor(MBB.getFallThrough()) != Loop) { - TII->negateCondBranch(&MI); - action_opcode = XVM::BREAK; - } - // Check if we need to add a break statement at the end of loop - int LevelBreakAfterLoop = -1; - if (action_opcode == XVM::CONTINUE) { - // 1. if the last stmt of the BB is a conditional branch statement and - // 2. if the next BB is one of its successor and - // 3. if the first statements of the next BB are END_BLOCK/END_LOOP - // insert a break if the above conditions are true - MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(); - MachineInstr &MITmp = *MBBI; - if (MITmp.isTerminator() && TII->isCondBranch(&MITmp)) { - MachineBasicBlock *NextBB = MBB.getNextNode(); - bool NextBBIsSucc = false; - for (auto *Succ : MBB.successors()) { - if (Succ == NextBB) { - NextBBIsSucc = true; - break; - } - } - if (NextBBIsSucc) { - MachineBasicBlock::const_iterator MBBINext = NextBB->begin(), ENext = NextBB->end(); - while (MBBINext != ENext) { - MachineBasicBlock::const_iterator NMBBINext = std::next(MBBINext); - const MachineInstr &MINext = *MBBINext; - if (MINext.getOpcode() == XVM::END_BLOCK || MINext.getOpcode() == XVM::END_LOOP) { - LevelBreakAfterLoop ++; - } else { - break; - } - MBBINext = NMBBINext; - } - } + uint32_t action_opcode = XVM::CONTINUE; + /* Fix Loop Exiting Fallthrough */ + if (&MBB == Loop->getBottomBlock() && &MI == &*(--MBB.end()) && MLI.getLoopFor(MBB.getFallThrough()) != Loop) { + TII->negateCondBranch(&MI); + action_opcode = XVM::BREAK; } - } - MachineInstr *MIThen = MBB.getParent()->CreateMachineInstr(TII->get(XVM::THEN), DebugLoc()); - MBB.insertAfter(MI.getIterator(), MIThen); - MachineInstr *MIAction = MBB.getParent()->CreateMachineInstr(TII->get(action_opcode), DebugLoc()); - MBB.insertAfter(MIThen->getIterator(), MIAction); - MachineInstr *MIEndThen = MBB.getParent()->CreateMachineInstr(TII->get(XVM::END_THEN), DebugLoc()); - MBB.insertAfter(MIAction->getIterator(), MIEndThen); - if (LevelBreakAfterLoop >= 0) { - MachineInstr *MIElse = MBB.getParent()->CreateMachineInstr(TII->get(XVM::ELSE), DebugLoc()); - MBB.insertAfter(MIEndThen->getIterator(), MIElse); - MachineInstr *MI_BREAK_IMM = MBB.getParent()->CreateMachineInstr(TII->get(XVM::BREAK_IMM), DebugLoc()); - MBB.insertAfter(MIElse->getIterator(), MI_BREAK_IMM); - MachineInstrBuilder MIB(MF, MI_BREAK_IMM); - MIB.addImm(LevelBreakAfterLoop); - MachineInstr *MIEndElse = MBB.getParent()->CreateMachineInstr(TII->get(XVM::END_ELSE), DebugLoc()); - MBB.insertAfter(MI_BREAK_IMM->getIterator(), MIEndElse); - MachineInstr *MIEndIf = MBB.getParent()->CreateMachineInstr(TII->get(XVM::END_IF), DebugLoc()); - MBB.insertAfter(MIEndElse->getIterator(), MIEndIf); - ChangeBranchCondOpc(MI, TII); - } else { + MachineInstr *MIThen = MBB.getParent()->CreateMachineInstr(TII->get(XVM::THEN), DebugLoc()); + MBB.insertAfter(MI.getIterator(), MIThen); + MachineInstr *MIAction = MBB.getParent()->CreateMachineInstr(TII->get(action_opcode), DebugLoc()); + MBB.insertAfter(MIThen->getIterator(), MIAction); + MachineInstr *MIEndThen = MBB.getParent()->CreateMachineInstr(TII->get(XVM::END_THEN), DebugLoc()); + MBB.insertAfter(MIAction->getIterator(), MIEndThen); MachineInstr *MIEndIf = MBB.getParent()->CreateMachineInstr(TII->get(XVM::END_IF), DebugLoc()); MBB.insertAfter(MIEndThen->getIterator(), MIEndIf); ChangeBranchCondOpc(MI, TII); - } } } } @@ -455,224 +413,230 @@ void XVMCFGStackify::removeInFunctionRet(MachineFunction &MF) { } /// Insert LOOP/BLOCK markers at appropriate places. -void XVMCFGStackify::placeMarkers(MachineFunction &MFunction) { - // To accommodate for the possible fake block we may insert at the end - // we allocate one more than the number of blocks in the func - ScopeTops.resize(MFunction.getNumBlockIDs() + 1); - // If MBB is the header of a loop, place the LOOP for MBB. - for (auto &MBBlock : MFunction) - placeLoopMarker(MBBlock); - - for (auto &MBBlock : MFunction) { +void XVMCFGStackify::placeMarkers(MachineFunction &MF) { + // We allocate one more than the number of blocks in the function to + // accommodate for the possible fake block we may insert at the end. + ScopeTops.resize(MF.getNumBlockIDs() + 1); + // Place the LOOP for MBB if MBB is the header of a loop. + for (auto &MBB : MF) + placeLoopMarker(MBB); + + for (auto &MBB : MF) { // Place the BLOCK for MBB if MBB is branched to from above. - placeBlockMarker(MBBlock); + placeBlockMarker(MBB); } - removeInFunctionRet(MFunction); + removeInFunctionRet(MF); } /// Insert a BLOCK marker for branches to MBB (if needed). // Note: Consider a more generalized way of handling block (and also loop and // try) signatures when we implement the multi-value proposal later. -void XVMCFGStackify::placeBlockMarker(MachineBasicBlock &MBBlock) { - assert(!MBBlock.isEHPad()); - MachineFunction &MFunction = *MBBlock.getParent(); +void XVMCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) { + assert(!MBB.isEHPad()); + MachineFunction &MF = *MBB.getParent(); auto &MDT = getAnalysis(); - const auto &TII = *MFunction.getSubtarget().getInstrInfo(); - - // For all forward non-fallthrough predecessors, compute the nearest commomn - // dominator, reduceing stack height, by minimizing the time the block is on the stack - MachineBasicBlock *Head = nullptr; - bool BranchedTo = false; - int MBBlockNumber = MBBlock.getNumber(); - for (MachineBasicBlock *Predecessor : MBBlock.predecessors()) { - if (Predecessor->getNumber() < MBBlockNumber) { - Head = Head ? MDT.findNearestCommonDominator(Head, Predecessor) : Predecessor; - if (explicitlyBranchesTo(Predecessor, &MBBlock)) - BranchedTo = true; + const auto &TII = *MF.getSubtarget().getInstrInfo(); + + // First compute the nearest common dominator of all forward non-fallthrough + // predecessors so that we minimize the time that the BLOCK is on the stack, + // which reduces overall stack height. + MachineBasicBlock *Header = nullptr; + bool IsBranchedTo = false; + int MBBNumber = MBB.getNumber(); + for (MachineBasicBlock *Pred : MBB.predecessors()) { + if (Pred->getNumber() < MBBNumber) { + Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred; + if (explicitlyBranchesTo(Pred, &MBB)) + IsBranchedTo = true; } } - if (!(Head && BranchedTo)) + if (!Header) + return; + if (!IsBranchedTo) return; - assert(&MBBlock != &MFunction.front() && "Header blocks shouldn't have predecessors"); - MachineBasicBlock *LayoutPredecessors = MBBlock.getPrevNode(); + assert(&MBB != &MF.front() && "Header blocks shouldn't have predecessors"); + MachineBasicBlock *LayoutPred = MBB.getPrevNode(); - // walk out to the nearest scope which isnt more deeply nester, if the nearest - // common cominator is inside a more deeply nested context - for (MachineFunction::iterator Iter(LayoutPredecessors), E(Head); Iter != E; --Iter) { - if (MachineBasicBlock *ST = ScopeTops[Iter->getNumber()]) { - if (ST->getNumber() > Head->getNumber()) { - // Intervening scope, skip - Iter = std::next(ST->getIterator()); + // If the nearest common dominator is inside a more deeply nested context, + // walk out to the nearest scope which isn't more deeply nested. + for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) { + if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) { + if (ScopeTop->getNumber() > Header->getNumber()) { + // Skip over an intervening scope. + I = std::next(ScopeTop->getIterator()); } else { - // scope level at an appropriate depth. end - Head = ST; + // We found a scope level at an appropriate depth. + Header = ScopeTop; break; } } } - // Where in Head should we put the block - // pre block instruction set - SmallPtrSet Before; - // post block instruction set - SmallPtrSet After; - for (const auto &MInst : *Head) { - // If the bottom block of the loop is above MBB and there is a previosly placed - // LOOP marker, it should be after the BLOCK, because the loop is nested inside it - // Otherwise it should be before the BLOCK - if (MInst.getOpcode() == XVM::LOOP) { - auto *LoopBot = BeginToEnd[&MInst]->getParent()->getPrevNode(); - if (MBBlock.getNumber() > LoopBot->getNumber()) - After.insert(&MInst); + // Decide where in Header to put the BLOCK. + + // Instructions that should go before the BLOCK. + SmallPtrSet BeforeSet; + // Instructions that should go after the BLOCK. + SmallPtrSet AfterSet; + for (const auto &MI : *Header) { + // If there is a previously placed LOOP marker and the bottom block of the + // loop is above MBB, it should be after the BLOCK, because the loop is + // nested in this BLOCK. Otherwise it should be before the BLOCK. + if (MI.getOpcode() == XVM::LOOP) { + auto *LoopBottom = BeginToEnd[&MI]->getParent()->getPrevNode(); + if (MBB.getNumber() > LoopBottom->getNumber()) + AfterSet.insert(&MI); #ifndef NDEBUG else - Before.insert(&MInst); + BeforeSet.insert(&MI); #endif } - // If an END marker is before the current BLOCK's END marker, and its - // corresponding BLOCK/TRY has been previously places, that should be palced - // after this BLOCK, otherwise is hould before. - if (MInst.getOpcode() == XVM::BLOCK) { - if (BeginToEnd[&MInst]->getParent()->getNumber() <= MBBlock.getNumber()) - After.insert(&MInst); + // If there is a previously placed BLOCK/TRY marker and its corresponding + // END marker is before the current BLOCK's END marker, that should be + // placed after this BLOCK. Otherwise it should be placed before this BLOCK + // marker. + if (MI.getOpcode() == XVM::BLOCK) { + if (BeginToEnd[&MI]->getParent()->getNumber() <= MBB.getNumber()) + AfterSet.insert(&MI); #ifndef NDEBUG else - Before.insert(&MInst); + BeforeSet.insert(&MI); #endif } -#ifndef NDEBUG // END_(BLOCK|LOOP|TRY) markers should all be before the BLOCK. - if (MInst.getOpcode() == XVM::END_BLOCK || - MInst.getOpcode() == XVM::END_LOOP) - Before.insert(&MInst); +#ifndef NDEBUG + // All END_(BLOCK|LOOP|TRY) markers should be before the BLOCK. + if (MI.getOpcode() == XVM::END_BLOCK || + MI.getOpcode() == XVM::END_LOOP) + BeforeSet.insert(&MI); #endif - if (MInst.isTerminator()) // Terminators should go after the BLOCK. - After.insert(&MInst); + // Terminators should go after the BLOCK. + if (MI.isTerminator()) + AfterSet.insert(&MI); } - // Local expression tree are placed after the BLOCK. - for (auto Iter = Head->getFirstTerminator(), E = Head->begin(); Iter != E; --Iter) { - if (std::prev(Iter)->isDebugInstr() || std::prev(Iter)->isPosition()) + // Local expression tree should go after the BLOCK. + for (auto I = Header->getFirstTerminator(), E = Header->begin(); I != E; + --I) { + if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition()) continue; - if (isChild(*std::prev(Iter))) - After.insert(&*std::prev(Iter)); + if (isChild(*std::prev(I))) + AfterSet.insert(&*std::prev(I)); else break; } // Add the BLOCK. // XVM::BlockType ReturnType = XVM::BlockType::Void; - auto InsertPosition = getLatestInsertPos(Head, Before, After); + auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet); MachineInstr *Begin = - BuildMI(*Head, InsertPosition, Head->findDebugLoc(InsertPosition), + BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos), TII.get(XVM::BLOCK)); //Note: Check if we need it later - // Decide where in Head to put the END_BLOCK. - Before.clear(); - After.clear(); - for (auto &MInst : MBBlock) { + // Decide where in Header to put the END_BLOCK. + BeforeSet.clear(); + AfterSet.clear(); + for (auto &MI : MBB) { #ifndef NDEBUG // END_BLOCK should precede existing LOOP and TRY markers. - if (MInst.getOpcode() == XVM::LOOP) - After.insert(&MInst); + if (MI.getOpcode() == XVM::LOOP) + AfterSet.insert(&MI); #endif - // If the head of the loop is above this block's head, and there is a - // previously places END_LOOP marker, the END_LOOp should be inserted - // after the BLOCK, since the loop contains this block, otherwise, it - // should be places before. the for END_TRY - if (MInst.getOpcode() == XVM::END_LOOP) { - if (EndToBegin[&MInst]->getParent()->getNumber() >= Head->getNumber()) - Before.insert(&MInst); + // If there is a previously placed END_LOOP marker and the header of the + // loop is above this block's header, the END_LOOP should be placed after + // the BLOCK, because the loop contains this block. Otherwise the END_LOOP + // should be placed before the BLOCK. The same for END_TRY. + if (MI.getOpcode() == XVM::END_LOOP) { + if (EndToBegin[&MI]->getParent()->getNumber() >= Header->getNumber()) + BeforeSet.insert(&MI); #ifndef NDEBUG else - After.insert(&MInst); + AfterSet.insert(&MI); #endif } } - // End of the block marker. - InsertPosition = getEarliestInsertPos(&MBBlock, Before, After); - MachineInstr *End = BuildMI(MBBlock, InsertPosition, MBBlock.findPrevDebugLoc(InsertPosition), + // Mark the end of the block. + InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet); + MachineInstr *End = BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos), TII.get(XVM::END_BLOCK)); registerScope(Begin, End); // Track the farthest-spanning scope that ends at this point. - updateScopeTops(Head, &MBBlock); + updateScopeTops(Header, &MBB); } /// Insert a LOOP marker for a loop starting at MBB (if it's a loop header). -void XVMCFGStackify::placeLoopMarker(MachineBasicBlock &MBBlock) { - MachineFunction &MFunction = *MBBlock.getParent(); - const auto &MLInfo = getAnalysis(); - SortRegionInfo SRI(MLInfo); - const auto &TII = *MFunction.getSubtarget().getInstrInfo(); - - MachineLoop *MLoop = MLInfo.getLoopFor(&MBBlock); - if (!MLoop || MLoop->getHeader() != &MBBlock) { +void XVMCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) { + MachineFunction &MF = *MBB.getParent(); + const auto &MLI = getAnalysis(); + SortRegionInfo SRI(MLI); + const auto &TII = *MF.getSubtarget().getInstrInfo(); + + MachineLoop *Loop = MLI.getLoopFor(&MBB); + if (!Loop || Loop->getHeader() != &MBB) return; - } // The operand of a LOOP is the first block after the loop. If the loop is the // bottom of the function, insert a dummy block at the end. - MachineBasicBlock *Bot = SRI.getBottom(MLoop); - auto I = std::next(Bot->getIterator()); - if (I == MFunction.end()) { - getAppendixBlock(MFunction); - I = std::next(Bot->getIterator()); + MachineBasicBlock *Bottom = SRI.getBottom(Loop); + auto Iter = std::next(Bottom->getIterator()); + if (Iter == MF.end()) { + getAppendixBlock(MF); + Iter = std::next(Bottom->getIterator()); } - MachineBasicBlock *AfterLoop = &*I; - - // Find where in Header to put the MLOOP. - SmallPtrSet Before; - SmallPtrSet After; - for (const auto &MInst : MBBlock) { - // Add a loop tag here, after any existing loop. - // Otherwise, we assume that the instruction is a loop. - if (MInst.getOpcode() == XVM::END_LOOP) - Before.insert(&MInst); + MachineBasicBlock *AfterLoop = &*Iter; + + // Decide where in Header to put the LOOP. + SmallPtrSet BeforeSet; + SmallPtrSet AfterSet; + for (const auto &MI : MBB) { + // LOOP marker should be after any existing loop that ends here. Otherwise + // we assume the instruction belongs to the loop. + if (MI.getOpcode() == XVM::END_LOOP) + BeforeSet.insert(&MI); #ifndef NDEBUG else - After.insert(&MInst); + AfterSet.insert(&MI); #endif } - // tag the start of the loop. - auto InsertPosition = getEarliestInsertPos(&MBBlock, Before, After); + // Mark the beginning of the loop. + auto InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet); //Note: modify the form of the LOOP instruction - MachineInstr *Begin = BuildMI(MBBlock, InsertPosition, MBBlock.findDebugLoc(InsertPosition), + MachineInstr *Begin = BuildMI(MBB, InsertPos, MBB.findDebugLoc(InsertPos), TII.get(XVM::LOOP)); // Decide where in Header to put the END_LOOP. - Before.clear(); - After.clear(); + BeforeSet.clear(); + AfterSet.clear(); #ifndef NDEBUG - for (const auto &MInst : MBBlock) - // The current loop is not associated with the existing END_LOOP markers, - // which belong to the parent loops. - if (MInst.getOpcode() == XVM::END_LOOP) - After.insert(&MInst); + for (const auto &MI : MBB) + // Existing END_LOOP markers belong to parent loops of this loop + if (MI.getOpcode() == XVM::END_LOOP) + AfterSet.insert(&MI); #endif // Mark the end of the loop (using arbitrary debug location that branched to // the loop end as its location). - InsertPosition = getEarliestInsertPos(AfterLoop, Before, After); + InsertPos = getEarliestInsertPos(AfterLoop, BeforeSet, AfterSet); DebugLoc EndDL = AfterLoop->pred_empty() - ? DebugLoc() - : (*AfterLoop->pred_rbegin())->findBranchDebugLoc(); - - MachineInstr *End = BuildMI(*AfterLoop, InsertPosition, EndDL, TII.get(XVM::END_LOOP)); + ? DebugLoc() + : (*AfterLoop->pred_rbegin())->findBranchDebugLoc(); + MachineInstr *End = + BuildMI(*AfterLoop, InsertPos, EndDL, TII.get(XVM::END_LOOP)); registerScope(Begin, End); assert((!ScopeTops[AfterLoop->getNumber()] || - ScopeTops[AfterLoop->getNumber()]->getNumber() < MBBlock.getNumber()) && - "With block sorting the outermost loop for a block should be first."); - updateScopeTops(&MBBlock, AfterLoop); + ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) && + "With block sorting the outermost loop for a block should be first."); + updateScopeTops(&MBB, AfterLoop); } void XVMCFGStackify::extendCondStmt(std::map CondBranchsWithDepth, @@ -711,7 +675,7 @@ void XVMCFGStackify::rewriteDepthImmediates(MachineFunction &MF) { // Now rewrite references to basic blocks to be depth immediates. std::map CondBranchsWithDepth; TII = MF.getSubtarget().getInstrInfo(); - SmallVector Stack; + SmallVector Stack; std::set SetEndBlockLoop; SmallVector EHPadStack; for (auto &MBB : reverse(MF)) { @@ -736,8 +700,8 @@ void XVMCFGStackify::rewriteDepthImmediates(MachineFunction &MF) { case XVM::END_LOOP: { Stack.push_back(std::make_pair(EndToBegin[&MI]->getParent(), &MI)); MachineInstr *PrevMI = MI.getPrevNode(); - if (PrevMI != NULL) { - if (PrevMI->getOpcode() == XVM::END_BLOCK || PrevMI->getOpcode() == XVM::END_LOOP) { + if (PrevMI != NULL && PrevMI == MBB.begin()) { + if (PrevMI->getOpcode() == XVM::END_BLOCK) { SetEndBlockLoop.insert(&MBB); } } @@ -746,7 +710,7 @@ void XVMCFGStackify::rewriteDepthImmediates(MachineFunction &MF) { default: if (MI.isTerminator()) { // Rewrite MBB operands to be depth immediates. - SmallVector Ops(MI.operands()); + SmallVector Ops(MI.operands()); unsigned int Opcode = MI.getOpcode(); unsigned int depth = 0; while (MI.getNumOperands() > 0) @@ -774,9 +738,9 @@ void XVMCFGStackify::rewriteDepthImmediates(MachineFunction &MF) { } void XVMCFGStackify::cleanupFunctionData(MachineFunction &MF) { - if (FakeBBlockCaller) - MF.deleteMachineBasicBlock(FakeBBlockCaller); - AppendixBBlock = FakeBBlockCaller = nullptr; + if (FakeCallerBB) + MF.deleteMachineBasicBlock(FakeCallerBB); + AppendixBB = FakeCallerBB = nullptr; } void XVMCFGStackify::releaseMemory() { @@ -789,6 +753,7 @@ bool XVMCFGStackify::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n" "********** Function: " << MF.getName() << '\n'); + releaseMemory(); // Place the BLOCK/LOOP/TRY markers to indicate the beginnings of scopes. diff --git a/llvm/lib/Target/XVM/XVMCFGStructure.cpp b/llvm/lib/Target/XVM/XVMCFGStructure.cpp index d7c8cd4ce02e..db76d9468f30 100644 --- a/llvm/lib/Target/XVM/XVMCFGStructure.cpp +++ b/llvm/lib/Target/XVM/XVMCFGStructure.cpp @@ -13,8 +13,6 @@ using namespace llvm; #define DEBUG_TYPE "xvm-cfg-structure" -#define INIT_SMALL_VECTOR_MO_SIZE 4 -#define INIT_SMALL_VECTOR_LOOP_SIZE 16 namespace { class XVMCFGStructure final : public MachineFunctionPass { @@ -205,10 +203,10 @@ void XVMCFGStructure::fixLoops(MachineBasicBlock &MBB) { auto &MLI = getAnalysis(); const auto &TII = MF->getSubtarget().getInstrInfo(); MachineLoop *Loop = MLI.getLoopFor(&MBB); - SmallVector ExitingBlocks; + SmallVector ExitingBlocks; auto &MPDT = getAnalysis(); using DomTreeT = PostDomTreeBase; - SmallVector PDTUpdates; + SmallVector PDTUpdates; if (!Loop || Loop->getHeader() != &MBB) // MBB must be loop head return; diff --git a/llvm/lib/Target/XVM/XVMErrorMsg.h b/llvm/lib/Target/XVM/XVMErrorMsg.h deleted file mode 100644 index c1e468ab85aa..000000000000 --- a/llvm/lib/Target/XVM/XVMErrorMsg.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- XVMErrorMsg.h - Error Message interface for XVM Backend ------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===---------------------------------------------------------------------------===// - -#ifndef __XVM__ERROR_MSG__HH__ -#define __XVM__ERROR_MSG__HH__ - -#include "llvm/Analysis/ConstantFolding.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/IR/DiagnosticInfo.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" -#include -#include -#include - -using namespace llvm; - -static inline void ExportFailMsg(const Function &Func, DebugLoc DL, const char *Msg, void *Val) { - std::string Str; - raw_string_ostream OS(Str); - OS << Msg; - if (Val != NULL) { - uint64_t *ValToPrint = (uint64_t *)Val; - OS << ":" << *ValToPrint; - } - Func.getContext().diagnose(DiagnosticInfoUnsupported(Func, Str, DL)); -} - -#endif // __XVM__ERROR_MSG__HH__ diff --git a/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp b/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp index f908e62beb33..5e75f124bf2a 100644 --- a/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/XVM/XVMExpandPseudoInsts.cpp @@ -1,15 +1,3 @@ -//===-- XVMExpandPseudoInsts.cpp - XVM Pseudo Instruction Expander ----------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------------------===// -// -// This file contains the XVM implementation of replacing certain Pseudoinstructions. -// -//===----------------------------------------------------------------------------------===// - #ifdef XVM_DYLIB_MODE #include "XVM.h" @@ -21,9 +9,6 @@ using namespace llvm; #define XVM_EXPAND_PSEUDO_NAME "XVM pseudo instruction expansion pass" -#define MO_FIRST 0 -#define MO_SECOND 1 -#define MO_THIRD 2 namespace { class XVMExpandPseudo : public MachineFunctionPass { @@ -139,8 +124,8 @@ bool XVMExpandPseudo::expandSelectCC(MachineBasicBlock &MBB, unsigned NewCC = getBranchOpcodeFromSelectCC(MI); BuildMI(MBB, MBBI, DL, TII->get(NewCC)).addMBB(TMBB) - .add(MI.getOperand(MO_SECOND)) - .add(MI.getOperand(MO_THIRD)); + .add(MI.getOperand(1)) + .add(MI.getOperand(2)); BuildMI(MBB, MBBI, DL, TII->get(XVM::BR)).addMBB(FMBB); MBB.addSuccessor(TMBB); MBB.addSuccessor(FMBB); @@ -185,7 +170,8 @@ bool XVMExpandPseudo::expandSelectCC(MachineBasicBlock &MBB, INITIALIZE_PASS(XVMExpandPseudo, "xvm-expand-pseudo", XVM_EXPAND_PSEUDO_NAME, false, false) namespace llvm { - FunctionPass *createXVMExpandPseudoPass() { return new XVMExpandPseudo(); } + +FunctionPass *createXVMExpandPseudoPass() { return new XVMExpandPseudo(); } } #endif diff --git a/llvm/lib/Target/XVM/XVMFrameLowering.cpp b/llvm/lib/Target/XVM/XVMFrameLowering.cpp index 5b544d4b2e8a..bacd68abd954 100644 --- a/llvm/lib/Target/XVM/XVMFrameLowering.cpp +++ b/llvm/lib/Target/XVM/XVMFrameLowering.cpp @@ -53,7 +53,8 @@ XVMFrameLowering::getOpcGlobSet(const MachineFunction &MF) { } void XVMFrameLowering::emitPrologue(MachineFunction &MF, - MachineBasicBlock &MBB) const { + MachineBasicBlock &MBB) const +{ auto &MFI = MF.getFrameInfo(); if (!needsSP(MF)) { return; @@ -73,7 +74,8 @@ void XVMFrameLowering::emitPrologue(MachineFunction &MF, } void XVMFrameLowering::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { + MachineBasicBlock &MBB) const +{ uint64_t StackSize = MF.getFrameInfo().getStackSize(); if (!needsSP(MF)) { return; @@ -94,7 +96,8 @@ void XVMFrameLowering::emitEpilogue(MachineFunction &MF, void XVMFrameLowering::determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, - RegScavenger *RS) const { + RegScavenger *RS) const +{ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); } diff --git a/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp b/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp index 9317eafa7f1a..2909d9bfbeeb 100644 --- a/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp +++ b/llvm/lib/Target/XVM/XVMISelDAGToDAG.cpp @@ -34,7 +34,6 @@ using namespace llvm; #define DEBUG_TYPE "xvm-isel" -#define TEMPLATE_INT_16 16 // Instruction Selector Implementation namespace { @@ -52,22 +51,20 @@ public: return "XVM DAG->DAG Pattern Instruction Selection"; } - bool runOnMachineFunction(MachineFunction &MFunc) override { + bool runOnMachineFunction(MachineFunction &MF) override { LLVM_DEBUG(dbgs() << "********** XVMDAGToDAGISel **********\n" "********** Function: " - << MFunc.getName() << '\n'); + << MF.getName() << '\n'); // Reset the subtarget each time through. - Subtarget = &MFunc.getSubtarget(); - return SelectionDAGISel::runOnMachineFunction(MFunc); + Subtarget = &MF.getSubtarget(); + return SelectionDAGISel::runOnMachineFunction(MF); } void PreprocessISelDAG() override; - bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, std::vector &OutOps) override; - private: -// The pieces autogenerated from the target description are included. +// Include the pieces autogenerated from the target description. #include "XVMGenDAGISel.inc" void Select(SDNode *N) override; @@ -79,108 +76,113 @@ private: } // namespace // ComplexPattern used on XVM Load/Store instructions -bool XVMDAGToDAGISel::SelectAddr(SDValue Address, SDValue &Bas, SDValue &Offs) { +bool XVMDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { // if Address is FI, get the TargetFrameIndex. - SDLoc DL(Address); - if (auto *FIN = dyn_cast(Address)) { - Bas = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); - Offs = CurDAG->getTargetConstant(0, DL, MVT::i64); + SDLoc DL(Addr); + if (auto *FIN = dyn_cast(Addr)) { + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); + Offset = CurDAG->getTargetConstant(0, DL, MVT::i64); return true; } - if (Address.getOpcode() == ISD::TargetExternalSymbol || - Address.getOpcode() == ISD::TargetGlobalAddress) + if (Addr.getOpcode() == ISD::TargetExternalSymbol || + Addr.getOpcode() == ISD::TargetGlobalAddress) return false; // Addresses of the form Addr+const or Addr|const - if (CurDAG->isBaseWithConstantOffset(Address)) { - auto *CN = cast(Address.getOperand(1)); - if (isInt(CN->getSExtValue())) { + if (CurDAG->isBaseWithConstantOffset(Addr)) { + auto *CN = cast(Addr.getOperand(1)); + if (isInt<16>(CN->getSExtValue())) { // If the first operand is a FI, get the TargetFI Node - if (auto *FIN = dyn_cast(Address.getOperand(0))) - Bas = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); + if (auto *FIN = dyn_cast(Addr.getOperand(0))) + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); else - Bas = Address.getOperand(0); + Base = Addr.getOperand(0); - Offs = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64); + Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64); return true; } } - Bas = Address; - Offs = CurDAG->getTargetConstant(0, DL, MVT::i64); + Base = Addr; + Offset = CurDAG->getTargetConstant(0, DL, MVT::i64); return true; } // ComplexPattern used on XVM FI instruction -bool XVMDAGToDAGISel::SelectFIAddr(SDValue Addr, SDValue &Base, SDValue &Offs) { +bool XVMDAGToDAGISel::SelectFIAddr(SDValue Addr, SDValue &Base, + SDValue &Offset) { SDLoc DL(Addr); - if (CurDAG->isBaseWithConstantOffset(Addr)) { - auto *CN = cast(Addr.getOperand(1)); - if (isInt(CN->getSExtValue())) { - if (auto *FIN = dyn_cast(Addr.getOperand(0))) { - Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); - Offs = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64); - return true; - } + if (!CurDAG->isBaseWithConstantOffset(Addr)) { + return false; + } + + // Addresses of the form Addr+const or Addr|const + auto *CN = cast(Addr.getOperand(1)); + if (isInt<16>(CN->getSExtValue())) { + // If the first operand is a FI, get the TargetFI Node + if (auto *FIN = dyn_cast(Addr.getOperand(0))) + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); + else { + return false; } + Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i64); + return true; } return false; } bool XVMDAGToDAGISel::SelectInlineAsmMemoryOperand( - const SDValue &Operand, unsigned ConstraintCode, std::vector &OutOps) { - bool ret = false; - SDValue Operand0, Operand1; + const SDValue &Op, unsigned ConstraintCode, std::vector &OutOps) { + SDValue Op0, Op1; switch (ConstraintCode) { + default: + return true; case InlineAsm::Constraint_m: // memory - if (!SelectAddr(Operand, Operand0, Operand1)) { - ret = true; + if (!SelectAddr(Op, Op0, Op1)) { + return true; } break; - default: - ret = true; } - if (ret == false) { - SDLoc DL(Operand); - SDValue AluOperand = CurDAG->getTargetConstant(ISD::ADD, DL, MVT::i32); - OutOps.push_back(Operand0); - OutOps.push_back(Operand1); - OutOps.push_back(AluOperand); - } - - return ret; + SDLoc DL(Op); + SDValue AluOp = CurDAG->getTargetConstant(ISD::ADD, DL, MVT::i32);; + OutOps.push_back(Op0); + OutOps.push_back(Op1); + OutOps.push_back(AluOp); + return false; } -void XVMDAGToDAGISel::Select(SDNode *CNode) { - unsigned Op = CNode->getOpcode(); +void XVMDAGToDAGISel::Select(SDNode *Node) { + unsigned Opcode = Node->getOpcode(); - // We have already selected if we have a custom node - if (CNode->isMachineOpcode()) { - LLVM_DEBUG(dbgs() << "== "; - CNode->dump(CurDAG); dbgs() << '\n'); + // If we have a custom node, we already have selected! + if (Node->isMachineOpcode()) { + LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << '\n'); return; } - switch (Op) { // handle table gen selection - case ISD::FrameIndex: - { - int FI = cast(CNode)->getIndex(); - EVT VT = CNode->getValueType(0); + // tablegen selection should be handled here. + switch (Opcode) { + default: + break; + case ISD::FrameIndex: { + int FI = cast(Node)->getIndex(); + EVT VT = Node->getValueType(0); SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); unsigned Opc = XVM::MOV_rr; - if (CNode->hasOneUse()) - CurDAG->SelectNodeTo(CNode, Opc, VT, TFI); - else - ReplaceNode(CNode, CurDAG->getMachineNode(Opc, SDLoc(CNode), VT, TFI)); + if (Node->hasOneUse()) { + CurDAG->SelectNodeTo(Node, Opc, VT, TFI); + return; + } + ReplaceNode(Node, CurDAG->getMachineNode(Opc, SDLoc(Node), VT, TFI)); + return; } - break; - default: - SelectCode(CNode); // select default instr } - return; + + // Select the default instruction + SelectCode(Node); } void XVMDAGToDAGISel::PreprocessISelDAG() { @@ -189,5 +191,4 @@ void XVMDAGToDAGISel::PreprocessISelDAG() { FunctionPass *llvm::createXVMISelDag(XVMTargetMachine &TM) { return new XVMDAGToDAGISel(TM); } - #endif diff --git a/llvm/lib/Target/XVM/XVMISelLowering.cpp b/llvm/lib/Target/XVM/XVMISelLowering.cpp index 179486601186..b22b034e1d28 100644 --- a/llvm/lib/Target/XVM/XVMISelLowering.cpp +++ b/llvm/lib/Target/XVM/XVMISelLowering.cpp @@ -10,6 +10,7 @@ // selection DAG. // //===----------------------------------------------------------------------===// + #ifdef XVM_DYLIB_MODE #include "XVM_def.h" @@ -21,7 +22,16 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" +#include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include #include #include @@ -29,22 +39,6 @@ using namespace llvm; #define DEBUG_TYPE "xvm-lower" -#define ALIGN_NUM_BYTES 8 -#define INIT_SMALL_VECTOR_SIZE 16 -#define INIT_SMALL_VECTOR_REGS_SIZE 6 -#define INIT_SMALL_VECTOR_OP_CHAIN_SIZE 10 -#define INIT_SMALL_VECTOR_OPS_SIZE 8 -#define INIT_SMALL_VECTOR_RETOP_SIZE 4 - -#define NUM_BITS_PER_BYTE 8 -#define SIZE_REF_IN_BYTES 8 -#define XVM_MAX_RET_SIZE 1 - -#define CHAIN_FIRST 0 -#define CHAIN_SECOND 1 -#define CHAIN_THIRD 2 - -#define TEMPLATE_INT_32 32 static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg) { MachineFunction &MF = DAG.getMachineFunction(); @@ -52,11 +46,12 @@ static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg) { DiagnosticInfoUnsupported(MF.getFunction(), Msg, DL.getDebugLoc())); } -static int shiftAndGet16Bits(uint64_t num, int n) { +static int ShiftAndGet16Bits(uint64_t num, int n) { return (num >> n) & 0xFFFF; } -static bool isValidImmediateSize(int32_t imm) { +static bool is_valid_immediate_size(int32_t imm) +{ return imm <= 0x3FFF && imm >= 0; } @@ -64,7 +59,8 @@ static bool hasFP(const MachineFunction &MF) { return false; } -static bool needsSPForLocalFrame(const MachineFunction &MF) { +static bool needsSPForLocalFrame( + const MachineFunction &MF) { auto &MFI = MF.getFrameInfo(); return MFI.getStackSize() || MFI.adjustsStack() || hasFP(MF); } @@ -79,10 +75,10 @@ static unsigned getBranchOpcodeFromSelectCC(MachineInstr &MI) { "The instruction should be a pseudo select cc!"); bool IsRROp = MI.getOpcode() == XVM::PseudoSelectCC_rr; if (!IsRROp) { - int64_t imm32 = MI.getOperand(MO_THIRD).getImm(); - IsRROp = !(isValidImmediateSize(imm32)); + int64_t imm32 = MI.getOperand(2).getImm(); + IsRROp = !(is_valid_immediate_size(imm32)); } - unsigned Cond = MI.getOperand(MO_FOURTH).getImm(); + unsigned Cond = MI.getOperand(3).getImm(); unsigned NewCond; switch (Cond) { #define SET_NEWCC(X, Y) \ @@ -100,14 +96,14 @@ static unsigned getBranchOpcodeFromSelectCC(MachineInstr &MI) { SET_NEWCC(SETLE, BSLE); SET_NEWCC(SETULE, BULE); default: - report_fatal_error("unimplemented select CondCode " + Twine(Cond)); + report_fatal_error("unimplemented select CondCode " + Twine(Cond)); } return NewCond; } XVMTargetLowering::XVMTargetLowering(const TargetMachine &TM, const XVMSubtarget &STI) - : TargetLowering(TM), Subtarget(STI) { + : TargetLowering(TM), Subtarget(&STI) { // Set up the register classes. addRegisterClass(MVT::i64, &XVM::XVMGPRRegClass); @@ -122,13 +118,8 @@ XVMTargetLowering::XVMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SETCC, MVT::i64, Expand); setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); - setOperationAction(ISD::SREM, MVT::i64, Expand); - setOperationAction(ISD::UREM, MVT::i64, Expand); - setOperationAction(ISD::SDIVREM, MVT::i64, Expand); - setOperationAction(ISD::UDIVREM, MVT::i64, Expand); - setOperationAction(ISD::BR_JT, MVT::Other, Expand); - setOperationAction(ISD::BRIND, MVT::Other, Custom); + setOperationAction(ISD::BRIND, MVT::Other, Expand); setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); @@ -155,25 +146,6 @@ XVMTargetLowering::XVMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::BSWAP, MVT::i64, Expand); - setOperationAction(ISD::BlockAddress, MVT::i64, Custom); - - setOperationAction(ISD::MULHU, MVT::i64, Custom); - setOperationAction(ISD::MULHS, MVT::i64, Custom); - setOperationAction(ISD::SMUL_LOHI, MVT::i64, Custom); - setOperationAction(ISD::UMUL_LOHI, MVT::i64, Custom); - - setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i64, Custom); - setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i64, Custom); - setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i64, Custom); - setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, Custom); - setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Custom); - setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, MVT::i64, Custom); - - setOperationAction(ISD::SREM, MVT::i64, Expand); - setOperationAction(ISD::UREM, MVT::i64, Expand); - setOperationAction(ISD::SDIVREM, MVT::i64, Expand); - setOperationAction(ISD::UDIVREM, MVT::i64, Expand); - // Extended load operations for i1 types must be promoted for (MVT VT : MVT::integer_valuetypes()) { setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); @@ -193,8 +165,8 @@ XVMTargetLowering::XVMTargetLowering(const TargetMachine &TM, setBooleanContents(ZeroOrOneBooleanContent); // Function alignments - setMinFunctionAlignment(Align(ALIGN_NUM_BYTES)); - setPrefFunctionAlignment(Align(ALIGN_NUM_BYTES)); + setMinFunctionAlignment(Align(8)); + setPrefFunctionAlignment(Align(8)); unsigned CommonMaxStores = (unsigned) 0xFFFFFFFF; MaxStoresPerMemset = MaxStoresPerMemsetOptSize = CommonMaxStores; @@ -234,39 +206,50 @@ bool XVMTargetLowering::isZExtFree(EVT VT1, EVT VT2) const { } XVMTargetLowering::ConstraintType -XVMTargetLowering::getConstraintType(StringRef CType) const { - if (CType.size() == 1) - if (CType[0] == 'w') +XVMTargetLowering::getConstraintType(StringRef Constraint) const { + if (Constraint.size() == 1) { + switch (Constraint[0]) { + default: + break; + case 'w': return C_RegisterClass; + } + } - return TargetLowering::getConstraintType(CType); + return TargetLowering::getConstraintType(Constraint); } std::pair XVMTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, - StringRef CType, MVT VT) const { - if (CType.size() == 1) // GCC Constraint Letters - if (CType[0] == 'r') // GENERAL_REGS + StringRef Constraint, + MVT VT) const { + if (Constraint.size() == 1) + // GCC Constraint Letters + switch (Constraint[0]) { + case 'r': // GENERAL_REGS return std::make_pair(0U, &XVM::XVMGPRRegClass); + default: + break; + } - return TargetLowering::getRegForInlineAsmConstraint(TRI, CType, VT); + return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); } -void XVMTargetLowering::ReplaceNodeResults(SDNode *N, +void XVMTargetLowering::ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const { const char *err_msg = nullptr; - uint32_t Op = N->getOpcode(); - switch (Op) { - case ISD::ATOMIC_LOAD_XOR: + uint32_t Opcode = N->getOpcode(); + switch (Opcode) { + default: + report_fatal_error("Unhandled custom legalization"); + case ISD::ATOMIC_LOAD_ADD: case ISD::ATOMIC_LOAD_AND: case ISD::ATOMIC_LOAD_OR: - case ISD::ATOMIC_LOAD_ADD: - case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: + case ISD::ATOMIC_LOAD_XOR: case ISD::ATOMIC_SWAP: + case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: break; - default: - report_fatal_error("Unhandled custom legalization"); } SDLoc DL(N); @@ -285,142 +268,108 @@ SDValue XVMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { return LowerVASTART(Op, DAG); case ISD::VAARG: return LowerVAARG(Op, DAG); - case ISD::DYNAMIC_STACKALLOC: { - SDNode *N = Op.getNode(); - SDLoc DL(N); - fail(DL, DAG, "Unsupported dynamic stack allocation"); - exit(1); - } - case ISD::BRIND: { - SDNode *N = Op.getNode(); - SDLoc DL(N); - fail(DL, DAG, "Unsupported Indirect Branch"); - exit(1); - } - case ISD::ATOMIC_LOAD_ADD: - case ISD::ATOMIC_LOAD_AND: - case ISD::ATOMIC_LOAD_OR: - case ISD::ATOMIC_LOAD_XOR: - case ISD::ATOMIC_SWAP: - case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: { - SDNode *N = Op.getNode(); - SDLoc DL(N); - fail(DL, DAG, "Unsupported Atomic Instructions"); - exit(1); - } - case ISD::MULHU: - case ISD::MULHS: - case ISD::SMUL_LOHI: - case ISD::UMUL_LOHI: { - SDNode *N = Op.getNode(); - SDLoc DL(N); - fail(DL, DAG, "Unsupported multiplication overflow"); - exit(1); - } - case ISD::BlockAddress: { - SDNode *N = Op.getNode(); - SDLoc DL(N); - fail(DL, DAG, "BlockAddress currently unsupported"); - exit(1); - } - default: { - SDNode *N = Op.getNode(); - SDLoc DL(N); - fail(DL, DAG, "unimplemented operand"); - break; - } + case ISD::DYNAMIC_STACKALLOC: + report_fatal_error("Unsupported dynamic stack allocation"); + default: + llvm_unreachable("unimplemented operand"); } } // Calling Convention Implementation #include "XVMGenCallingConv.inc" -SDValue XVMTargetLowering::LowerFormalArguments(SDValue Nodes, CallingConv::ID Call, bool IsVar, - const SmallVectorImpl &In, const SDLoc &DLoc, - SelectionDAG &DAGraph, SmallVectorImpl &Vals) const { - switch (Call) { +SDValue XVMTargetLowering::LowerFormalArguments( + SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Ins, const SDLoc &DL, + SelectionDAG &DAG, SmallVectorImpl &InVals) const { + switch (CallConv) { + default: + report_fatal_error("Unsupported calling convention"); case CallingConv::C: case CallingConv::Fast: break; - default: - report_fatal_error("Calling convention unsupported"); } - MachineFunction &MFunction = DAGraph.getMachineFunction(); - MachineRegisterInfo &RInfo = MFunction.getRegInfo(); - - // All incoming arguments are assigned locations. - SmallVector ArgLoc; - CCState CCInfo(Call, IsVar, MFunction, ArgLoc, *DAGraph.getContext()); - CCInfo.AnalyzeFormalArguments(In, CC_XVM64); - bool doesNeedSP = needsSP(MFunction); - - for (auto &LocIterator : ArgLoc) { - if (LocIterator.isRegLoc()) { - // Register passed args - EVT VT = LocIterator.getLocVT(); - MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; - switch (SVT) { - default: - errs() << "LowerFormalArguments Unhandled argument type: " << VT.getEVTString() << '\n'; + MachineFunction &MF = DAG.getMachineFunction(); + MachineRegisterInfo &RegInfo = MF.getRegInfo(); + + // Assign locations to all of the incoming arguments. + SmallVector ArgLocs; + CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CC_XVM64); + bool doesNeedSP = needsSP(MF); + + for (auto &VA : ArgLocs) { + if (VA.isRegLoc()) { + // Arguments passed in registers + EVT RegVT = VA.getLocVT(); + MVT::SimpleValueType SimpleTy = RegVT.getSimpleVT().SimpleTy; + switch (SimpleTy) { + default: { + errs() << "LowerFormalArguments Unhandled argument type: " + << RegVT.getEVTString() << '\n'; llvm_unreachable(nullptr); + } case MVT::i32: case MVT::i64: - Register VRegister = RInfo.createVirtualRegister(&XVM::XVMGPRRegClass); - RInfo.addLiveIn(LocIterator.getLocReg(), VRegister); - SDValue ArgV = DAGraph.getCopyFromReg(Nodes, DLoc, VRegister, VT); - //insert an assert[sz]ext tp capture a value being promoted to a wider type - if (LocIterator.getLocInfo() == CCValAssign::SExt) - ArgV = DAGraph.getNode(ISD::AssertSext, DLoc, VT, ArgV, - DAGraph.getValueType(LocIterator.getValVT())); - else if (LocIterator.getLocInfo() == CCValAssign::ZExt) - ArgV = DAGraph.getNode(ISD::AssertZext, DLoc, VT, ArgV, - DAGraph.getValueType(LocIterator.getValVT())); - - if (LocIterator.getLocInfo() != CCValAssign::Full) - ArgV = DAGraph.getNode(ISD::TRUNCATE, DLoc, LocIterator.getValVT(), ArgV); - - Vals.push_back(ArgV); - break; + Register VReg = RegInfo.createVirtualRegister(&XVM::XVMGPRRegClass); + RegInfo.addLiveIn(VA.getLocReg(), VReg); + SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT); + + // If this is an value that has been promoted to wider types, insert an + // assert[sz]ext to capture this, then truncate to the right size. + if (VA.getLocInfo() == CCValAssign::SExt) + ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue, + DAG.getValueType(VA.getValVT())); + else if (VA.getLocInfo() == CCValAssign::ZExt) + ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue, + DAG.getValueType(VA.getValVT())); + + if (VA.getLocInfo() != CCValAssign::Full) + ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue); + + InVals.push_back(ArgValue); + + break; } } else { - MVT LocVT = LocIterator.getLocVT(); - MachineFrameInfo &MFI = MFunction.getFrameInfo(); - EVT ValVT = LocIterator.getValVT(); - // sanity check - assert(LocIterator.isMemLoc()); - /* The stack pointer offset is relative to the caller stack frame. - * we also need to add the offset created in in callee for saving callee saved regs - * we do not need to consider further callee stack offset, - * it will be handled later in eliminateFrameIndex - */ - int FI = 0; - if (doesNeedSP) { - const MCPhysReg *CSRegs = MFunction.getRegInfo().getCalleeSavedRegs(); - unsigned CSRcounter = 0; - for (; CSRegs[CSRcounter]; ++CSRcounter); - FI = MFI.CreateFixedObject(ValVT.getSizeInBits()/NUM_BITS_PER_BYTE, - LocIterator.getLocMemOffset() + CSRcounter*SIZE_REF_IN_BYTES, true); - } else { - FI = MFI.CreateFixedObject(ValVT.getSizeInBits()/NUM_BITS_PER_BYTE, - LocIterator.getLocMemOffset(), true); - } + MVT LocVT = VA.getLocVT(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + EVT ValVT = VA.getValVT(); + // sanity check + assert(VA.isMemLoc()); + /* The stack pointer offset is relative to the caller stack frame. + * we also need to add the offset created in in callee for saving callee saved regs + * we do not need to consider further callee stack offset, + * it will be handled later in eliminateFrameIndex + */ + int FI = 0; + if (doesNeedSP) { + const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs(); + unsigned CSRcounter = 0; + for (; CSRegs[CSRcounter]; ++CSRcounter); + FI = MFI.CreateFixedObject(ValVT.getSizeInBits()/8, + VA.getLocMemOffset() + CSRcounter*8, true); + } else { + FI = MFI.CreateFixedObject(ValVT.getSizeInBits()/8, + VA.getLocMemOffset(), true); + } - // Create load nodes to retrieve arguments from the stack - SDValue FIN = DAGraph.getFrameIndex(FI, getPointerTy(DAGraph.getDataLayout())); - SDValue Load = DAGraph.getLoad( - LocVT, DLoc, Nodes, FIN, - MachinePointerInfo::getFixedStack(DAGraph.getMachineFunction(), FI)); - Vals.push_back(Load); + // Create load nodes to retrieve arguments from the stack + SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); + SDValue Load = DAG.getLoad( + LocVT, DL, Chain, FIN, + MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)); + InVals.push_back(Load); } } std::vector OutChains; - if (IsVar) { + if (IsVarArg) { const TargetRegisterClass *RC = &XVM::XVMGPRRegClass; - MachineFrameInfo &MFI = MFunction.getFrameInfo(); - MachineRegisterInfo &RegInfo = MFunction.getRegInfo(); - XVMMachineFunctionInfo *XFI = MFunction.getInfo(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + MachineRegisterInfo &RegInfo = MF.getRegInfo(); + XVMMachineFunctionInfo *XFI = MF.getInfo(); static const MCPhysReg ArgGPRs[] = {XVM::R0, XVM::R1, XVM::R2, XVM::R3, XVM::R4, XVM::R5}; ArrayRef ArgRegs = makeArrayRef(ArgGPRs); @@ -433,12 +382,12 @@ SDValue XVMTargetLowering::LowerFormalArguments(SDValue Nodes, CallingConv::ID C VaArgOffset = CCInfo.getNextStackOffset(); VaArgsSaveSize = 0; } else { - VaArgsSaveSize = SIZE_REF_IN_BYTES * (ArgRegs.size() - FirstRegIdx); + VaArgsSaveSize = 8 * (ArgRegs.size() - FirstRegIdx); VaArgOffset = -VaArgsSaveSize; } XFI->SetVarArgsFrameIndex( - MFI.CreateFixedObject(SIZE_REF_IN_BYTES, // size + MFI.CreateFixedObject(8, // size VaArgOffset, // SPOffset true)); // IsImmutable // Copy the registers that have not been used for var argument passing @@ -446,10 +395,10 @@ SDValue XVMTargetLowering::LowerFormalArguments(SDValue Nodes, CallingConv::ID C for (unsigned I = FirstRegIdx; I < ArgRegs.size(); I++, VaArgOffset += 8) { const Register Reg = RegInfo.createVirtualRegister(RC); RegInfo.addLiveIn(ArgRegs[I], Reg); - SDValue ArgV = DAGraph.getCopyFromReg(Nodes, DLoc, Reg, MVT::i64); + SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, MVT::i64); int FI = MFI.CreateFixedObject(8, VaArgOffset, true); - SDValue FrameIndex = DAGraph.getFrameIndex(FI, getPointerTy(DAGraph.getDataLayout())); - SDValue Store = DAGraph.getStore(Nodes, DLoc, ArgV, FrameIndex, MachinePointerInfo::getFixedStack(MFunction, FI)); + SDValue FrameIndex = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); + SDValue Store = DAG.getStore(Chain, DL, ArgValue, FrameIndex, MachinePointerInfo::getFixedStack(MF, FI)); // Init the mem operand always. cast(Store.getNode())->getMemOperand()->setValue((Value*)nullptr); OutChains.push_back(Store); @@ -457,219 +406,216 @@ SDValue XVMTargetLowering::LowerFormalArguments(SDValue Nodes, CallingConv::ID C } if (!OutChains.empty()) { - OutChains.push_back(Nodes); - Nodes = DAGraph.getNode(ISD::TokenFactor, DLoc, MVT::Other, OutChains); + OutChains.push_back(Chain); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains); } - return Nodes; + return Chain; } -SDValue XVMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLoweringInfo, - SmallVectorImpl &Vals) const { - auto &In = CLoweringInfo.Ins; - auto &Out = CLoweringInfo.Outs; - SDValue Nodes = CLoweringInfo.Chain; - auto &OutValues = CLoweringInfo.OutVals; - SDValue Called = CLoweringInfo.Callee; - bool IsVArg = CLoweringInfo.IsVarArg; - SelectionDAG &DAGraph = CLoweringInfo.DAG; - bool &IsTail = CLoweringInfo.IsTailCall; - CallingConv::ID CallConvention = CLoweringInfo.CallConv; - MachineFunction &MFunction = DAGraph.getMachineFunction(); +SDValue XVMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const { + SelectionDAG &DAG = CLI.DAG; + auto &Outs = CLI.Outs; + auto &OutVals = CLI.OutVals; + auto &Ins = CLI.Ins; + SDValue Chain = CLI.Chain; + SDValue Callee = CLI.Callee; + bool &IsTailCall = CLI.IsTailCall; + CallingConv::ID CallConv = CLI.CallConv; + bool IsVarArg = CLI.IsVarArg; + MachineFunction &MF = DAG.getMachineFunction(); // XVM target does not support tail call optimization. - IsTail = false; + IsTailCall = false; - switch (CallConvention) { - case CallingConv::C: + switch (CallConv) { + default: + report_fatal_error("Unsupported calling convention"); case CallingConv::Fast: + case CallingConv::C: break; - default: - report_fatal_error("calling convention unsupported"); } - - const XVMRegisterInfo *TRI = Subtarget.getRegisterInfo(); - const uint32_t *Mask = TRI->getCallPreservedMask(MFunction, CallConvention); + const XVMRegisterInfo *TRI = Subtarget->getRegisterInfo(); + const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv); assert(Mask && "Missing call preserved mask for calling convention"); // Analyze operands of the call, assigning locations to each operand. - SmallVector ArgLocs; - CCState CCInfo(CallConvention, IsVArg, MFunction, ArgLocs, *DAGraph.getContext()); + SmallVector ArgLocs; + CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(Out, CC_XVM64); + CCInfo.AnalyzeCallOperands(Outs, CC_XVM64); unsigned NumBytes = CCInfo.getNextStackOffset(); - for (auto &Arg : Out) { + for (auto &Arg : Outs) { ISD::ArgFlagsTy Flags = Arg.Flags; if (!Flags.isByVal()) continue; } - auto PtrVT = getPointerTy(MFunction.getDataLayout()); - Nodes = DAGraph.getCALLSEQ_START(Nodes, NumBytes, 0, CLoweringInfo.DL); + auto PtrVT = getPointerTy(MF.getDataLayout()); + Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL); - SmallVector, INIT_SMALL_VECTOR_REGS_SIZE> PassingRegs; - SmallVector MemOpNodeChains; + SmallVector, 6> RegsToPass; + SmallVector MemOpChains; - SDValue StackP = DAGraph.getCopyFromReg(Nodes, CLoweringInfo.DL, XVM::SP, PtrVT); + SDValue StackPtr = DAG.getCopyFromReg(Chain, CLI.DL, XVM::SP, PtrVT); // Walk arg assignments - for (unsigned argnum = 0, e = Out.size(); argnum != e; ++argnum) { - SDValue Arg = OutValues[argnum]; - CCValAssign &CurrentArgloc = ArgLocs[argnum]; + for (unsigned i = 0, e = Outs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + SDValue Arg = OutVals[i]; // Promote the value if needed. - switch (CurrentArgloc.getLocInfo()) { + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unknown loc info"); case CCValAssign::Full: break; case CCValAssign::SExt: - Arg = DAGraph.getNode(ISD::SIGN_EXTEND, CLoweringInfo.DL, CurrentArgloc.getLocVT(), Arg); - break; - case CCValAssign::AExt: - Arg = DAGraph.getNode(ISD::ANY_EXTEND, CLoweringInfo.DL, CurrentArgloc.getLocVT(), Arg); + Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg); break; case CCValAssign::ZExt: - Arg = DAGraph.getNode(ISD::ZERO_EXTEND, CLoweringInfo.DL, CurrentArgloc.getLocVT(), Arg); + Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg); + break; + case CCValAssign::AExt: + Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg); break; - default: - llvm_unreachable("Unknown loc info"); } - // Push arguments into Passingregs vector - if (CurrentArgloc.isRegLoc()) - PassingRegs.push_back(std::make_pair(CurrentArgloc.getLocReg(), Arg)); + // Push arguments into RegsToPass vector + if (VA.isRegLoc()) + RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); else { - assert(CurrentArgloc.isMemLoc()); + assert(VA.isMemLoc()); - int32_t Offset = CurrentArgloc.getLocMemOffset(); - SDValue PtrOff = DAGraph.getIntPtrConstant(Offset, CLoweringInfo.DL); + int32_t Offset = VA.getLocMemOffset(); + SDValue PtrOff = DAG.getIntPtrConstant(Offset, CLI.DL); - SDValue DstAddr = DAGraph.getNode(ISD::ADD, CLoweringInfo.DL, PtrVT, StackP, PtrOff); - MachinePointerInfo DstInfo = MachinePointerInfo::getStack(MFunction, Offset); + SDValue DstAddr = DAG.getNode(ISD::ADD, CLI.DL, PtrVT, StackPtr, PtrOff); + MachinePointerInfo DstInfo = MachinePointerInfo::getStack(MF, Offset); - SDValue Store = DAGraph.getStore(Nodes, CLoweringInfo.DL, Arg, DstAddr, DstInfo); - MemOpNodeChains.push_back(Store); + SDValue Store = DAG.getStore(Chain, CLI.DL, Arg, DstAddr, DstInfo); + MemOpChains.push_back(Store); } } - if (!MemOpNodeChains.empty()) - Nodes = DAGraph.getNode(ISD::TokenFactor, CLoweringInfo.DL, MVT::Other, MemOpNodeChains); + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, CLI.DL, MVT::Other, MemOpChains); - SDValue IFlag; + SDValue InFlag; - // build a node dependency chain and flag operands that copy outgoing args to regs - // All emitted instructions have to be grouped togeher, hence IFLAG - for (auto &CurrentReg : PassingRegs) { - Nodes = DAGraph.getCopyToReg(Nodes, CLoweringInfo.DL, CurrentReg.first, CurrentReg.second, IFlag); - IFlag = Nodes.getValue(1); + // Build a sequence of copy-to-reg nodes chained together with token chain and + // flag operands which copy the outgoing args into registers. The InFlag in + // necessary since all emitted instructions must be stuck together. + for (auto &Reg : RegsToPass) { + Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InFlag); + InFlag = Chain.getValue(1); } - // if a GlobalAddress node is the "called" (every direct call is) - // change it to a TargetGlobalAddress so legalize doesnt hack it - // ExternelSymbol -> TargetExternelSymbol - if (GlobalAddressSDNode *GlblAddNode = dyn_cast(Called)) { - Called = DAGraph.getTargetGlobalAddress(GlblAddNode->getGlobal(), CLoweringInfo.DL, PtrVT, - GlblAddNode->getOffset(), 0); - } else if (ExternalSymbolSDNode *ExtSymbNode = dyn_cast(Called)) { - Called = DAGraph.getTargetExternalSymbol(ExtSymbNode->getSymbol(), PtrVT, 0); - if (strcmp(ExtSymbNode->getSymbol(), "__fixsfdi") == 0) { - fail(CLoweringInfo.DL, DAGraph, Twine("Floats are unsupported in XVM")); - exit(1); - } else { - fail(CLoweringInfo.DL, DAGraph, Twine("A call to built-in function '" - + StringRef(ExtSymbNode->getSymbol()) - + "' is not supported.")); - exit(1); - } + // If the callee is a GlobalAddress node (quite common, every direct call is) + // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + // Likewise ExternalSymbol -> TargetExternalSymbol. + if (GlobalAddressSDNode *G = dyn_cast(Callee)) { + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT, + G->getOffset(), 0); + } else if (ExternalSymbolSDNode *E = dyn_cast(Callee)) { + Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); + fail(CLI.DL, DAG, Twine("A call to built-in function '" + + StringRef(E->getSymbol()) + + "' is not supported.")); } - // Return a chain of nodes and a flag that retval copy can use. - SDVTList NodeTypes = DAGraph.getVTList(MVT::Other, MVT::Glue); - SmallVector Ops; - Ops.push_back(Nodes); - Ops.push_back(Called); - Ops.push_back(DAGraph.getRegisterMask(Mask)); - - // Make argument registers line into the call by appending them to the list - for (auto &RegIter : PassingRegs) - Ops.push_back(DAGraph.getRegister(RegIter.first, RegIter.second.getValueType())); - - if (IFlag.getNode()) - Ops.push_back(IFlag); - - Nodes = DAGraph.getNode(XVMISD::CALL, CLoweringInfo.DL, NodeTypes, Ops); - IFlag = Nodes.getValue(1); - - // CALLSEQ_END node created. - Nodes = DAGraph.getCALLSEQ_END(Nodes, - DAGraph.getConstant(NumBytes, CLoweringInfo.DL, PtrVT, true), - DAGraph.getConstant(0, CLoweringInfo.DL, PtrVT, true), - IFlag, CLoweringInfo.DL); - IFlag = Nodes.getValue(1); - - // copt result values from pregs to the returned vregs - return LowerCallResult(Nodes, IFlag, CallConvention, IsVArg, In, CLoweringInfo.DL, DAGraph, - Vals); -} - -SDValue XVMTargetLowering::LowerReturn(SDValue Nodes, CallingConv::ID CallConv, - bool IsVarArg, - const SmallVectorImpl &Outs, - const SmallVectorImpl &OutVals, - const SDLoc &DLoc, SelectionDAG &DAGraph) const { + // Returns a chain & a flag for retval copy to use. + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); + SmallVector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getRegisterMask(Mask)); + + // Add argument registers to the end of the list so that they are + // known live into the call. + for (auto &Reg : RegsToPass) + Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType())); + + if (InFlag.getNode()) + Ops.push_back(InFlag); + + Chain = DAG.getNode(XVMISD::CALL, CLI.DL, NodeTys, Ops); + InFlag = Chain.getValue(1); + + // Create the CALLSEQ_END node. + Chain = DAG.getCALLSEQ_END( + Chain, DAG.getConstant(NumBytes, CLI.DL, PtrVT, true), + DAG.getConstant(0, CLI.DL, PtrVT, true), InFlag, CLI.DL); + InFlag = Chain.getValue(1); + + // Handle result values, copying them out of physregs into vregs that we + // return. + return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, CLI.DL, DAG, + InVals); +} + +SDValue +XVMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, + const SDLoc &DL, SelectionDAG &DAG) const { unsigned Opc = XVMISD::RET_FLAG; // CCValAssign - represent the assignment of the return value to a location - SmallVector RVLocs; - MachineFunction &MFunction = DAGraph.getMachineFunction(); + SmallVector RVLocs; + MachineFunction &MF = DAG.getMachineFunction(); - // CCState - register and stack slot info. - CCState CCInfo(CallConv, IsVarArg, MFunction, RVLocs, *DAGraph.getContext()); + // CCState - Info about the registers and stack slot. + CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); - if (MFunction.getFunction().getReturnType()->isAggregateType()) { - fail(DLoc, DAGraph, "only integer returns supported"); - return DAGraph.getNode(Opc, DLoc, MVT::Other, Nodes); + if (MF.getFunction().getReturnType()->isAggregateType()) { + fail(DL, DAG, "only integer returns supported"); + return DAG.getNode(Opc, DL, MVT::Other, Chain); } - // return value analysis + // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_XVM64); - SDValue IFlag; - SmallVector RetOps(1, Nodes); + SDValue Flag; + SmallVector RetOps(1, Chain); - // insert our results into the output reg. - for (unsigned counter = 0; counter != RVLocs.size(); ++counter) { - CCValAssign &ValIter = RVLocs[counter]; - assert(ValIter.isRegLoc() && "Can only return in registers!"); + // Copy the result values into the output registers. + for (unsigned i = 0; i != RVLocs.size(); ++i) { + CCValAssign &VA = RVLocs[i]; + assert(VA.isRegLoc() && "Can only return in registers!"); - Nodes = DAGraph.getCopyToReg(Nodes, DLoc, ValIter.getLocReg(), OutVals[counter], IFlag); + Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad. - IFlag = Nodes.getValue(1); - RetOps.push_back(DAGraph.getRegister(ValIter.getLocReg(), ValIter.getLocVT())); + Flag = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); } - RetOps[0] = Nodes; // Update chain. + RetOps[0] = Chain; // Update chain. // Add the flag if we have it. - if (IFlag.getNode()) - RetOps.push_back(IFlag); + if (Flag.getNode()) + RetOps.push_back(Flag); - return DAGraph.getNode(Opc, DLoc, MVT::Other, RetOps); + return DAG.getNode(Opc, DL, MVT::Other, RetOps); } SDValue XVMTargetLowering::LowerCallResult( SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl &InVals) const { + MachineFunction &MF = DAG.getMachineFunction(); // Assign locations to each value returned by this call. - SmallVector RVLocs; + SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); - if (Ins.size() >= XVM_MAX_RET_SIZE + 1) { + if (Ins.size() >= 2) { fail(DL, DAG, "only small returns supported"); for (unsigned i = 0, e = Ins.size(); i != e; ++i) InVals.push_back(DAG.getConstant(0, DL, Ins[i].VT)); @@ -681,58 +627,58 @@ SDValue XVMTargetLowering::LowerCallResult( // Copy all of the result registers out of their specified physreg. for (auto &Val : RVLocs) { Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(), - Val.getValVT(), InFlag).getValue(CHAIN_SECOND); - InFlag = Chain.getValue(CHAIN_THIRD); - InVals.push_back(Chain.getValue(CHAIN_FIRST)); + Val.getValVT(), InFlag).getValue(1); + InFlag = Chain.getValue(2); + InVals.push_back(Chain.getValue(0)); } return Chain; } SDValue XVMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const { - SDValue CondV = Op.getOperand(MO_SECOND); + SDValue CondV = Op.getOperand(1); SDLoc DL(Op); if (CondV.getOpcode() == ISD::SETCC && - CondV.getOperand(MO_FIRST).getValueType() == MVT::i64) { - SDValue LHS = CondV.getOperand(MO_FIRST); - SDValue RHS = CondV.getOperand(MO_SECOND); + CondV.getOperand(0).getValueType() == MVT::i64) { + SDValue LHS = CondV.getOperand(0); + SDValue RHS = CondV.getOperand(1); - SDValue TargetCC = CondV.getOperand(MO_THIRD); + SDValue TargetCC = CondV.getOperand(2); return DAG.getNode(XVMISD::BR_CC, DL, Op.getValueType(), - Op.getOperand(MO_FIRST), LHS, RHS, TargetCC, Op.getOperand(MO_THIRD)); + Op.getOperand(0), LHS, RHS, TargetCC, Op.getOperand(2)); } else if (CondV.getOpcode() == ISD::AssertZext && - CondV.getOperand(MO_FIRST).getValueType() == MVT::i64) { - SDValue LHS = CondV.getOperand(MO_FIRST); + CondV.getOperand(0).getValueType() == MVT::i64) { + SDValue LHS = CondV.getOperand(0); SDValue RHS = DAG.getConstant(1, DL, MVT::i64); SDValue TargetCC = DAG.getCondCode(ISD::SETEQ); return DAG.getNode(XVMISD::BR_CC, DL, Op.getValueType(), - Op.getOperand(MO_FIRST), LHS, RHS, TargetCC, Op.getOperand(MO_THIRD)); + Op.getOperand(0), LHS, RHS, TargetCC, Op.getOperand(2)); } else if (CondV.getOpcode() == ISD::AND || CondV.getOpcode() == ISD::OR || - CondV.getOpcode() == ISD::XOR || CondV.getOpcode() == ISD::Constant || - CondV.getOpcode() == ISD::UADDO || CondV.getOpcode() == ISD::SELECT_CC || - CondV.getOpcode() == ISD::UREM || CondV.getOpcode() == ISD::SRL || - CondV.getOpcode() == ISD::SELECT) { + CondV.getOpcode() == ISD::XOR || CondV.getOpcode() == ISD::Constant) { SDValue LHS = CondV; + if (CondV.getNumOperands()>0) { + LHS = CondV.getOperand(0); + } SDValue RHS = DAG.getConstant(0, DL, MVT::i64); SDValue TargetCC = DAG.getCondCode(ISD::SETNE); return DAG.getNode(XVMISD::BR_CC, DL, Op.getValueType(), - Op.getOperand(MO_FIRST), LHS, RHS, TargetCC, Op.getOperand(MO_THIRD)); + Op.getOperand(0), LHS, RHS, TargetCC, Op.getOperand(2)); } //Note: complete the lowering for other cases later return Op; } SDValue XVMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { - SDValue LHS = Op.getOperand(MO_FIRST); - SDValue RHS = Op.getOperand(MO_SECOND); - SDValue TrueV = Op.getOperand(MO_THIRD); - SDValue FalseV = Op.getOperand(MO_FOURTH); - ISD::CondCode CC = cast(Op.getOperand(MO_FIFTH))->get(); + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + SDValue TrueV = Op.getOperand(2); + SDValue FalseV = Op.getOperand(3); + ISD::CondCode CC = cast(Op.getOperand(4))->get(); SDLoc DL(Op); SDValue TargetCC = DAG.getConstant(CC, DL, LHS.getValueType()); @@ -749,7 +695,7 @@ SDValue XVMTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { int VarArgsFrameIndex = MF.getInfo()->GetVarArgsFrameIndex(); SDValue FrameIndex = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy(MF.getDataLayout())); - SDValue RetSDValue = DAG.getStore(Op.getOperand(MO_FIRST), SDLoc(Op), FrameIndex, Op.getOperand(MO_SECOND), + SDValue RetSDValue = DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, Op.getOperand(1), MachinePointerInfo()); // unsigned AddressSpace = 0, int64_t offset = 0 return RetSDValue; @@ -762,10 +708,10 @@ SDValue XVMTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); MachinePointerInfo MPI(0U, 0L); EVT PointerType = getPointerTy(DAG.getMachineFunction().getDataLayout()); - SDValue LoadPointer = DAG.getLoad(PointerType, DL, Op.getOperand(MO_FIRST), Op.getOperand(MO_SECOND), MPI); + SDValue LoadPointer = DAG.getLoad(PointerType, DL, Op.getOperand(0), Op.getOperand(1), MPI); SDValue Offset = DAG.getConstant(8, DL, MVT::i64); SDValue AddPointer = DAG.getNode(ISD::ADD, DL, PointerType, LoadPointer, Offset); - SDValue StorePointer = DAG.getStore(LoadPointer.getValue(1), DL, AddPointer, Op.getOperand(MO_SECOND), MPI); + SDValue StorePointer = DAG.getStore(LoadPointer.getValue(1), DL, AddPointer, Op.getOperand(1), MPI); SDValue RetSDValue = DAG.getLoad(Op.getValueType(), DL, StorePointer, LoadPointer, MPI); return RetSDValue; } @@ -791,16 +737,16 @@ const char *XVMTargetLowering::getTargetNodeName(unsigned Opcode) const { } } -SDValue XVMTargetLowering::LowerGlobalAddress(SDValue Oper, - SelectionDAG &DAGraph) const { - auto NIter = cast(Oper); - assert(NIter->getOffset() == 0 && "global address offset invalid"); +SDValue XVMTargetLowering::LowerGlobalAddress(SDValue Op, + SelectionDAG &DAG) const { + auto N = cast(Op); + assert(N->getOffset() == 0 && "Invalid offset for global address"); - SDLoc DLoc(Oper); - const GlobalValue *GlobVal = NIter->getGlobal(); - SDValue GlobalAdd = DAGraph.getTargetGlobalAddress(GlobVal, DLoc, MVT::i64); + SDLoc DL(Op); + const GlobalValue *GV = N->getGlobal(); + SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i64); - return DAGraph.getNode(XVMISD::Wrapper, DLoc, MVT::i64, GlobalAdd); + return DAG.getNode(XVMISD::Wrapper, DL, MVT::i64, GA); } unsigned @@ -823,54 +769,55 @@ XVMTargetLowering::EmitInstrWithCustomInserterSelectCC(MachineInstr &MI, assert((isSelectRROp || isSelectRIOp) && "Unexpected instr type to insert"); #endif - // We insert a diamond control-flow pattern, to insert a SELECT instruction - // The incoming instruction holds the branch opcode, the true/false values, - // the condition code register to branch on and the dest vreg - const BasicBlock *LLVM_BasicB = BB->getBasicBlock(); - MachineFunction::iterator Iter = ++BB->getIterator(); - - // CurrentMBBlock: - // TrueValue = ... - // jmp_XX r1, r2 goto Copy1MBBlock - // fallthrough --> Copy0MBBlock - MachineBasicBlock *CurrentMBBlock = BB; - MachineFunction *MFunc = BB->getParent(); - MachineBasicBlock *Copy0MBBlock = MFunc->CreateMachineBasicBlock(LLVM_BasicB); - MachineBasicBlock *Copy1MBBlock = MFunc->CreateMachineBasicBlock(LLVM_BasicB); - - MFunc->insert(Iter, Copy0MBBlock); - MFunc->insert(Iter, Copy1MBBlock); - // The Phi node for the select will be in the new block, transferring - // all successors of the current block to the new one will update the - // machien-CFG edges - Copy1MBBlock->splice(Copy1MBBlock->begin(), BB, - std::next(MachineBasicBlock::iterator(MI)), BB->end()); - Copy1MBBlock->transferSuccessorsAndUpdatePHIs(BB); - // Add the true/fallthrough blocks as its successors. - BB->addSuccessor(Copy0MBBlock); - BB->addSuccessor(Copy1MBBlock); - - // if Flag insert branch + // To "insert" a SELECT instruction, we actually have to insert the diamond + // control-flow pattern. The incoming instruction knows the destination vreg + // to set, the condition code register to branch on, the true/false values to + // select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator I = ++BB->getIterator(); + + // ThisMBB: + // ... + // TrueVal = ... + // jmp_XX r1, r2 goto Copy1MBB + // fallthrough --> Copy0MBB + MachineBasicBlock *ThisMBB = BB; + MachineFunction *F = BB->getParent(); + MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); + + F->insert(I, Copy0MBB); + F->insert(I, Copy1MBB); + // Update machine-CFG edges by transferring all successors of the current + // block to the new block which will contain the Phi node for the select. + Copy1MBB->splice(Copy1MBB->begin(), BB, + std::next(MachineBasicBlock::iterator(MI)), BB->end()); + Copy1MBB->transferSuccessorsAndUpdatePHIs(BB); + // Next, add the true and fallthrough blocks as its successors. + BB->addSuccessor(Copy0MBB); + BB->addSuccessor(Copy1MBB); + + // Insert Branch if Flag int NewCC = getBranchOpcodeFromSelectCC(MI); - Register LHS = MI.getOperand(MO_SECOND).getReg(); + Register LHS = MI.getOperand(1).getReg(); if (isSelectRROp) { - Register RHS = MI.getOperand(MO_THIRD).getReg(); - BuildMI(BB, DL, TII.get(NewCC)).addMBB(Copy1MBBlock).addReg(LHS).addReg(RHS); + Register RHS = MI.getOperand(2).getReg(); + BuildMI(BB, DL, TII.get(NewCC)).addMBB(Copy1MBB).addReg(LHS).addReg(RHS); } else { - int64_t imm32 = MI.getOperand(MO_THIRD).getImm(); + int64_t imm32 = MI.getOperand(2).getImm(); // Check before we build J*_ri instruction. - assert (isInt(imm32)); - if (isValidImmediateSize(imm32)) { - BuildMI(BB, DL, TII.get(NewCC)).addMBB(Copy1MBBlock).addReg(LHS).addImm(imm32); + assert (isInt<32>(imm32)); + if (is_valid_immediate_size(imm32)) { + BuildMI(BB, DL, TII.get(NewCC)).addMBB(Copy1MBB).addReg(LHS).addImm(imm32); } else { Register ScratchReg; - MachineRegisterInfo &MRI = MFunc->getRegInfo(); + MachineRegisterInfo &MRI = F->getRegInfo(); ScratchReg = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - uint64_t MostSignificantBits = shiftAndGet16Bits(imm32, MOST_SIGNIFICANT); - uint64_t UpperMiddleBits = shiftAndGet16Bits(imm32, UPPER_MIDDLE); - uint64_t LowerMiddleBits = shiftAndGet16Bits(imm32, LOWER_MIDDLE); - uint64_t LeastSignificantBits = shiftAndGet16Bits(imm32, LEAST_SIGNIFICANT); + uint64_t MostSignificantBits = ShiftAndGet16Bits(imm32, 48); + uint64_t UpperMiddleBits = ShiftAndGet16Bits(imm32, 32); + uint64_t LowerMiddleBits = ShiftAndGet16Bits(imm32, 16); + uint64_t LeastSignificantBits = ShiftAndGet16Bits(imm32, 0); Register VRegForMov = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); BuildMI(BB, DL, TII.get(XVM::MOV_ri), VRegForMov).addImm(0); @@ -878,47 +825,47 @@ XVMTargetLowering::EmitInstrWithCustomInserterSelectCC(MachineInstr &MI, if (LeastSignificantBits) { Register VRegForMovk1 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); BuildMI(BB, DL, TII.get(XVM::MOVK_ri), VRegForMovk1) - .addReg(PrevReg).addImm(LeastSignificantBits).addImm(MOVK_SHIFT_0); + .addReg(PrevReg).addImm(LeastSignificantBits).addImm(0); PrevReg = VRegForMovk1; } if (LowerMiddleBits) { Register VRegForMovk2 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); BuildMI(BB, DL, TII.get(XVM::MOVK_ri), VRegForMovk2) - .addReg(PrevReg).addImm(LowerMiddleBits).addImm(MOVK_SHIFT_16); + .addReg(PrevReg).addImm(LowerMiddleBits).addImm(0); PrevReg = VRegForMovk2; } if (UpperMiddleBits) { Register VRegForMovk3 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); BuildMI(BB, DL, TII.get(XVM::MOVK_ri), VRegForMovk3) - .addReg(PrevReg).addImm(UpperMiddleBits).addImm(MOVK_SHIFT_32); + .addReg(PrevReg).addImm(UpperMiddleBits).addImm(0); PrevReg = VRegForMovk3; } if (MostSignificantBits) { Register VRegForMovk4 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); BuildMI(BB, DL, TII.get(XVM::MOVK_ri), VRegForMovk4) - .addReg(PrevReg).addImm(MostSignificantBits).addImm(MOVK_SHIFT_48); - PrevReg = VRegForMovk4; + .addReg(PrevReg).addImm(MostSignificantBits).addImm(0); } - BuildMI(BB, DL, TII.get(NewCC)).addMBB(Copy1MBBlock).addReg(LHS).addReg(PrevReg); + BuildMI(BB, DL, TII.get(NewCC)).addMBB(Copy1MBB).addReg(LHS).addReg(PrevReg); } } - // Copy0MBBlock: + // Copy0MBB: // %FalseValue = ... - // # fallthrough to Copy1MBBlock - BB = Copy0MBBlock; - - // machine-CFG edges, update - BB->addSuccessor(Copy1MBBlock); - - // Copy1MBBlock: - // %Result = phi [ %FalseValue, Copy0MBBlock ], [ %TrueValue, CurrentMBBlock ] - BB = Copy1MBBlock; - BuildMI(*BB, BB->begin(), DL, TII.get(XVM::PHI), MI.getOperand(MO_FIRST).getReg()) - .addReg(MI.getOperand(MO_SIXTH).getReg()) - .addMBB(Copy0MBBlock) - .addReg(MI.getOperand(MO_FIFTH).getReg()) - .addMBB(CurrentMBBlock); + // # fallthrough to Copy1MBB + BB = Copy0MBB; + + // Update machine-CFG edges + BB->addSuccessor(Copy1MBB); + + // Copy1MBB: + // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ] + // ... + BB = Copy1MBB; + BuildMI(*BB, BB->begin(), DL, TII.get(XVM::PHI), MI.getOperand(0).getReg()) + .addReg(MI.getOperand(5).getReg()) + .addMBB(Copy0MBB) + .addReg(MI.getOperand(4).getReg()) + .addMBB(ThisMBB); MI.eraseFromParent(); // The pseudo instruction is gone now. return BB; @@ -930,11 +877,11 @@ XVMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, DebugLoc DL = MI.getDebugLoc(); unsigned Opc = MI.getOpcode(); switch (Opc) { - case XVM::PseudoSelectCC_rr: - case XVM::PseudoSelectCC_ri: - return EmitInstrWithCustomInserterSelectCC(MI, BB); - default: - return BB; + case XVM::PseudoSelectCC_rr: + case XVM::PseudoSelectCC_ri: + return EmitInstrWithCustomInserterSelectCC(MI, BB); + default: + return BB; } } @@ -948,25 +895,26 @@ MVT XVMTargetLowering::getScalarShiftAmountTy(const DataLayout &DL, return MVT::i64; } -bool XVMTargetLowering::isLegalAddressingMode(const DataLayout &DLayout, const AddrMode &AMode, - Type *T, unsigned AS, Instruction *Inst) const { - // Globals are never allowed as a base - bool ret = true; - if (AMode.BaseGV) - ret = false; - else - switch (AMode.Scale) { - case 0: // "r+i" or "i", depends on HasBaseReg. +bool XVMTargetLowering::isLegalAddressingMode(const DataLayout &DL, + const AddrMode &AM, Type *Ty, + unsigned AS, + Instruction *I) const { + // No global is ever allowed as a base. + if (AM.BaseGV) + return false; + + switch (AM.Scale) { + case 0: // "r+i" or just "i", depending on HasBaseReg. + break; + case 1: + if (!AM.HasBaseReg) // allow "r+i". break; - case 1: - if (!AMode.HasBaseReg) // "r+i", allowed - break; - ret = false; // "r+r" or "r+r+i", not allowed - default: - ret = false; - } + return false; // disallow "r+r" or "r+r+i". + default: + return false; + } - return ret; + return true; } #endif diff --git a/llvm/lib/Target/XVM/XVMISelLowering.h b/llvm/lib/Target/XVM/XVMISelLowering.h index a9feb909343a..e631e358d278 100644 --- a/llvm/lib/Target/XVM/XVMISelLowering.h +++ b/llvm/lib/Target/XVM/XVMISelLowering.h @@ -51,7 +51,7 @@ public: bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; XVMTargetLowering::ConstraintType - getConstraintType(StringRef CType) const override; + getConstraintType(StringRef Constraint) const override; std::pair getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, @@ -67,7 +67,7 @@ public: MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override; private: - const XVMSubtarget &Subtarget; + const XVMSubtarget *Subtarget; SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; @@ -88,8 +88,8 @@ private: static const unsigned MaxArgs; // Lower a call into CALLSEQ_START - XVMISD:CALL - CALLSEQ_END chain - SDValue LowerCall(TargetLowering::CallLoweringInfo &CLoweringInfo, - SmallVectorImpl &Vals) const override; + SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const override; // Lower incoming arguments, copy physregs into vregs SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, @@ -98,11 +98,10 @@ private: const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl &InVals) const override; - SDValue LowerReturn(SDValue Nodes, CallingConv::ID CallConv, - bool IsVarArg, + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, - const SmallVectorImpl &OutVals, - const SDLoc &DLoc, SelectionDAG &DAGraph) const override; + const SmallVectorImpl &OutVals, const SDLoc &DL, + SelectionDAG &DAG) const override; void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG) const override; @@ -132,8 +131,9 @@ private: return false; } - bool isLegalAddressingMode(const DataLayout &DLayout, const AddrMode &AMode, - Type *T, unsigned AS, Instruction *Inst = nullptr) const override; + bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, + Type *Ty, unsigned AS, + Instruction *I = nullptr) const override; // isTruncateFree - Return true if it's free to truncate a value of // type Ty1 to type Ty2. e.g. On XVM at alu32 mode, it's free to truncate diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.cpp b/llvm/lib/Target/XVM/XVMInstrInfo.cpp index 6eb071424afa..c4b233cc6576 100644 --- a/llvm/lib/Target/XVM/XVMInstrInfo.cpp +++ b/llvm/lib/Target/XVM/XVMInstrInfo.cpp @@ -27,80 +27,73 @@ #include "XVMGenInstrInfo.inc" using namespace llvm; -#define NUM_MO_BRANCH_INSTR 3 -#define MO_FIRST 0 -#define MO_SECOND 1 -#define MO_THIRD 2 -#define MO_FOURTH 3 -#define NUM_OF_BRANCHES 2 - -static XVM::CondCode getCondFromBranchOpc(unsigned Opc) { +static CondCode getCondFromBranchOpc(unsigned Opc) { switch (Opc) { default: - return XVM::COND_INVALID; + return COND_INVALID; case XVM::BUEQ_rr: case XVM::BUEQ_ri: case XVM::BSEQ_ri: - return XVM::COND_EQ; + return COND_EQ; case XVM::BSNEQ_rr: case XVM::BSNEQ_ri: - return XVM::COND_NE; + return COND_NE; case XVM::BSGE_rr: case XVM::BSGE_ri: - return XVM::COND_GE; + return COND_GE; case XVM::BUGE_rr: case XVM::BUGE_ri: - return XVM::COND_UGE; + return COND_UGE; case XVM::BSLE_rr: case XVM::BSLE_ri: - return XVM::COND_LE; + return COND_LE; case XVM::BULE_rr: case XVM::BULE_ri: - return XVM::COND_ULE; + return COND_ULE; case XVM::BSGT_rr: case XVM::BSGT_ri: - return XVM::COND_GT; + return COND_GT; case XVM::BUGT_rr: case XVM::BUGT_ri: - return XVM::COND_UGT; + return COND_UGT; case XVM::BSLT_rr: case XVM::BSLT_ri: - return XVM::COND_LT; + return COND_LT; case XVM::BULT_rr: case XVM::BULT_ri: - return XVM::COND_ULT; + return COND_ULT; } } static unsigned getBranchOpcFromCond(ArrayRef &Cond) { - assert(Cond.size() == NUM_MO_BRANCH_INSTR && "Expected an operation and 2 operands!"); - assert(Cond[MO_FIRST].isImm() && "Expected an imm for operation!"); + assert(Cond.size() == 3 && "Expected an operation and 2 operands!"); + assert(Cond[0].isImm() && "Expected an imm for operation!"); - switch (Cond[MO_FIRST].getImm()) { + switch (Cond[0].getImm()) { default: //Invalid operation, bail out return 0; - case XVM::COND_EQ: - return Cond[MO_THIRD].isImm() ? XVM::BSEQ_ri : XVM::BUEQ_rr; - case XVM::COND_NE: - return Cond[MO_THIRD].isImm() ? XVM::BSNEQ_ri : XVM::BSNEQ_rr; - case XVM::COND_GE: - return Cond[MO_THIRD].isImm() ? XVM::BSGE_ri : XVM::BSGE_rr; - case XVM::COND_UGE: - return Cond[MO_THIRD].isImm() ? XVM::BUGE_ri : XVM::BUGE_rr; - case XVM::COND_LE: - return Cond[MO_THIRD].isImm() ? XVM::BSLE_ri : XVM::BSLE_rr; - case XVM::COND_ULE: - return Cond[MO_THIRD].isImm() ? XVM::BULE_ri : XVM::BULE_rr; - case XVM::COND_GT: - return Cond[MO_THIRD].isImm() ? XVM::BSGT_ri : XVM::BSGT_rr; - case XVM::COND_UGT: - return Cond[MO_THIRD].isImm() ? XVM::BUGT_ri : XVM::BUGT_rr; - case XVM::COND_LT: - return Cond[MO_THIRD].isImm() ? XVM::BSLT_ri : XVM::BSLT_rr; - case XVM::COND_ULT: - return Cond[MO_THIRD].isImm() ? XVM::BULT_ri : XVM::BULT_rr; + case COND_EQ: + return Cond[2].isImm() ? XVM::BSEQ_ri : XVM::BUEQ_rr; + case COND_NE: + return Cond[2].isImm() ? XVM::BSNEQ_ri : XVM::BSNEQ_rr; + case COND_GE: + return Cond[2].isImm() ? XVM::BSGE_ri : XVM::BSGE_rr; + case COND_UGE: + return Cond[2].isImm() ? XVM::BUGE_ri : XVM::BUGE_rr; + case COND_LE: + return Cond[2].isImm() ? XVM::BSLE_ri : XVM::BSLE_rr; + case COND_ULE: + return Cond[2].isImm() ? XVM::BULE_ri : XVM::BULE_rr; + case COND_GT: + return Cond[2].isImm() ? XVM::BSGT_ri : XVM::BSGT_rr; + case COND_UGT: + return Cond[2].isImm() ? XVM::BUGT_ri : XVM::BUGT_rr; + case COND_LT: + return Cond[2].isImm() ? XVM::BSLT_ri : XVM::BSLT_rr; + case COND_ULT: + return Cond[2].isImm() ? XVM::BULT_ri : XVM::BULT_rr; } } @@ -121,42 +114,43 @@ void XVMInstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } -static int shiftAndGet16Bits(uint64_t num, int n) { +static int ShiftAndGet16Bits(uint64_t num, int n) { return (num >> n) & 0xFFFF; } -static inline void ReplaceImmWithMovk(MachineBasicBlock *BB, - MachineBasicBlock::iterator MI, - DebugLoc dl) { +static inline void replace_imm_with_movk(MachineBasicBlock *BB, + MachineBasicBlock::iterator MI, + DebugLoc dl) +{ const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo(); - uint64_t imm = MI->getOperand(MO_THIRD).getImm(); - uint64_t MostSignificantBits = shiftAndGet16Bits(imm, MOST_SIGNIFICANT); - uint64_t UpperSignificantBits = shiftAndGet16Bits(imm, UPPER_MIDDLE); - uint64_t LowerSignificantBits = shiftAndGet16Bits(imm, LOWER_MIDDLE); - uint64_t LeastSignificantBits = shiftAndGet16Bits(imm, LEAST_SIGNIFICANT); - if (LeastSignificantBits) { + uint64_t imm = MI->getOperand(2).getImm(); + uint64_t most_significant_bits = ShiftAndGet16Bits(imm, 48); + uint64_t upper_significant_bits = ShiftAndGet16Bits(imm, 32); + uint64_t lower_significant_bits = ShiftAndGet16Bits(imm, 16); + uint64_t least_significant_bits = ShiftAndGet16Bits(imm, 0); + if (least_significant_bits) { BuildMI(*BB, MI, dl, TII.get(XVM::MOVK_ri)) - .addReg(XVM::R2, RegState::Define).addReg(XVM::R2).addImm(LeastSignificantBits).addImm(MOVK_SHIFT_0); + .addReg(XVM::R2, RegState::Define).addImm(0).addImm(least_significant_bits).addImm(0); } - if (LowerSignificantBits) { + if (lower_significant_bits) { BuildMI(*BB, MI, dl, TII.get(XVM::MOVK_ri)) - .addReg(XVM::R2, RegState::Define).addReg(XVM::R2).addImm(LowerSignificantBits).addImm(MOVK_SHIFT_16); + .addReg(XVM::R2, RegState::Define).addImm(0).addImm(lower_significant_bits).addImm(1); } - if (UpperSignificantBits) { + if (upper_significant_bits) { BuildMI(*BB, MI, dl, TII.get(XVM::MOVK_ri)) - .addReg(XVM::R2, RegState::Define).addReg(XVM::R2).addImm(UpperSignificantBits).addImm(MOVK_SHIFT_32); + .addReg(XVM::R2, RegState::Define).addImm(0).addImm(upper_significant_bits).addImm(2); } - if (MostSignificantBits) { + if (most_significant_bits) { BuildMI(*BB, MI, dl, TII.get(XVM::MOVK_ri)) - .addReg(XVM::R2, RegState::Define).addReg(XVM::R2).addImm(MostSignificantBits).addImm(MOVK_SHIFT_48); + .addReg(XVM::R2, RegState::Define).addImm(0).addImm(most_significant_bits).addImm(3); } } void XVMInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { int func_num = GetFuncIndex("memcpy"); MachineBasicBlock *BB = MI->getParent(); - Register DstReg = MI->getOperand(MO_FIRST).getReg(); - Register SrcReg = MI->getOperand(MO_SECOND).getReg(); + Register DstReg = MI->getOperand(0).getReg(); + Register SrcReg = MI->getOperand(1).getReg(); DebugLoc dl = MI->getDebugLoc(); BuildMI(*BB, MI, dl, get(XVM::LDD)) @@ -164,9 +158,9 @@ void XVMInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { BuildMI(*BB, MI, dl, get(XVM::LDD)) .addReg(XVM::R1, RegState::Define).addReg(SrcReg).addImm(0); if (MI->getOpcode() == XVM::MEMCPY_ri) { - ReplaceImmWithMovk(BB, MI, dl); + replace_imm_with_movk(BB, MI, dl); } else { - Register CopyLen = MI->getOperand(MO_THIRD).getReg(); + Register CopyLen = MI->getOperand(2).getReg(); BuildMI(*BB, MI, dl, get(XVM::LDD)) .addReg(XVM::R2, RegState::Define).addReg(CopyLen).addImm(0); } @@ -178,8 +172,8 @@ void XVMInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { void XVMInstrInfo::expandMEMMOVE(MachineBasicBlock::iterator MI) const { int func_num = GetFuncIndex("memmove"); MachineBasicBlock *BB = MI->getParent(); - Register DstReg = MI->getOperand(MO_FIRST).getReg(); - Register SrcReg = MI->getOperand(MO_SECOND).getReg(); + Register DstReg = MI->getOperand(0).getReg(); + Register SrcReg = MI->getOperand(1).getReg(); DebugLoc dl = MI->getDebugLoc(); BuildMI(*BB, MI, dl, get(XVM::LDD)) @@ -187,9 +181,9 @@ void XVMInstrInfo::expandMEMMOVE(MachineBasicBlock::iterator MI) const { BuildMI(*BB, MI, dl, get(XVM::LDD)) .addReg(XVM::R1, RegState::Define).addReg(SrcReg).addImm(0); if (MI->getOpcode() == XVM::MEMMOV_ri) { - ReplaceImmWithMovk(BB, MI, dl); + replace_imm_with_movk(BB, MI, dl); } else { - Register CopyLen = MI->getOperand(MO_THIRD).getReg(); + Register CopyLen = MI->getOperand(2).getReg(); BuildMI(*BB, MI, dl, get(XVM::LDD)) .addReg(XVM::R2, RegState::Define).addReg(CopyLen).addImm(0); } @@ -201,8 +195,8 @@ void XVMInstrInfo::expandMEMMOVE(MachineBasicBlock::iterator MI) const { void XVMInstrInfo::expandMEMSET(MachineBasicBlock::iterator MI) const { int func_num = GetFuncIndex("memset"); MachineBasicBlock *BB = MI->getParent(); - Register DstReg = MI->getOperand(MO_FIRST).getReg(); - Register SrcReg = MI->getOperand(MO_SECOND).getReg(); + Register DstReg = MI->getOperand(0).getReg(); + Register SrcReg = MI->getOperand(1).getReg(); DebugLoc dl = MI->getDebugLoc(); BuildMI(*BB, MI, dl, get(XVM::LDD)) @@ -210,9 +204,9 @@ void XVMInstrInfo::expandMEMSET(MachineBasicBlock::iterator MI) const { BuildMI(*BB, MI, dl, get(XVM::LDD)) .addReg(XVM::R1, RegState::Define).addReg(SrcReg).addImm(0); if (MI->getOpcode() == XVM::MEMSET_ri) { - ReplaceImmWithMovk(BB, MI, dl); + replace_imm_with_movk(BB, MI, dl); } else { - Register CopyLen = MI->getOperand(MO_THIRD).getReg(); + Register CopyLen = MI->getOperand(2).getReg(); BuildMI(*BB, MI, dl, get(XVM::LDD)) .addReg(XVM::R2, RegState::Define).addReg(CopyLen).addImm(0); } @@ -294,9 +288,9 @@ bool XVMInstrInfo::analyzeBranch(MachineBasicBlock &MBB, return true; case XVM::BR : if (!HaveCond) - TBB = MI.getOperand(MO_FIRST).getMBB(); + TBB = MI.getOperand(0).getMBB(); else - FBB = MI.getOperand(MO_FIRST).getMBB(); + FBB = MI.getOperand(0).getMBB(); break; case XVM::BUEQ_rr : case XVM::BSNEQ_rr : @@ -322,11 +316,11 @@ bool XVMInstrInfo::analyzeBranch(MachineBasicBlock &MBB, case XVM::BULT_ri : if (HaveCond) return true; - XVM::CondCode CC = getCondFromBranchOpc(MI.getOpcode()); + CondCode CC = getCondFromBranchOpc(MI.getOpcode()); Cond.push_back(MachineOperand::CreateImm(CC)); - Cond.push_back(MI.getOperand(MO_SECOND)); - Cond.push_back(MI.getOperand(MO_THIRD)); - TBB = MI.getOperand(MO_FIRST).getMBB(); + Cond.push_back(MI.getOperand(1)); + Cond.push_back(MI.getOperand(2)); + TBB = MI.getOperand(0).getMBB(); HaveCond = true; break; } @@ -351,15 +345,15 @@ unsigned XVMInstrInfo::insertBranch(MachineBasicBlock &MBB, return 1; } - assert(Cond.size() == NUM_MO_BRANCH_INSTR && "Expected 2 operands and an operation!"); + assert(Cond.size() == 3 && "Expected 2 operands and an operation!"); BuildMI(&MBB, DL, get(getBranchOpcFromCond(Cond))).addMBB(TBB) - .add(Cond[MO_SECOND]) - .add(Cond[MO_THIRD]); + .add(Cond[1]) + .add(Cond[2]); if (!FBB) return 1; BuildMI(&MBB, DL, get(XVM::BR)).addMBB(FBB); - return NUM_OF_BRANCHES; + return 2; } unsigned XVMInstrInfo::removeBranch(MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.h b/llvm/lib/Target/XVM/XVMInstrInfo.h index c62e22c80ee3..6e51f3969687 100644 --- a/llvm/lib/Target/XVM/XVMInstrInfo.h +++ b/llvm/lib/Target/XVM/XVMInstrInfo.h @@ -20,7 +20,7 @@ #include "XVMGenInstrInfo.inc" namespace llvm { -namespace XVM { + enum CondCode { COND_EQ, COND_NE, @@ -34,7 +34,6 @@ enum CondCode { COND_ULT, COND_INVALID }; -} class XVMInstrInfo : public XVMGenInstrInfo { const XVMRegisterInfo RI; diff --git a/llvm/lib/Target/XVM/XVMInstrInfo.td b/llvm/lib/Target/XVM/XVMInstrInfo.td index 09e5e0d6f0d3..8bb08ae9ac94 100644 --- a/llvm/lib/Target/XVM/XVMInstrInfo.td +++ b/llvm/lib/Target/XVM/XVMInstrInfo.td @@ -189,7 +189,7 @@ let isBranch = 1, hasCtrlDep = 1 in { def BREAK_IMM : ControFlowNoArgs<0b00001000, (outs), (ins uimm6:$imm), "break #$imm", []>; def CONTINUE : ControFlowNoArgs<0b00000000, (outs), (ins), "continue", []>; def THEN : ControFlowNoArgs<0b00000000, (outs), (ins), "(then", []>; - def END_THEN : ControFlowNoArgs<0b00000000, (outs), (ins), ") ;; end_then", []>; + def END_THEN : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; def ELSE : ControFlowNoArgs<0b00000000, (outs), (ins), "(else", []>; def END_ELSE : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; def END_IF : ControFlowNoArgs<0b00000000, (outs), (ins), ")", []>; @@ -288,7 +288,7 @@ def : Pat < (sub 0, i64:$src2), (NEG_r i64:$src2)>; // mov combinations def GetMovImm : SDNodeXFormgetTargetConstant( (N->getSExtValue() & 0x7fff), SDLoc(N), MVT::i64); + return CurDAG->getTargetConstant( (N->getSExtValue() & 0xffff), SDLoc(N), MVT::i64); }]>; def GetMovk0Imm : SDNodeXFormgetTargetConstant( (N->getSExtValue() & 0xffff), SDLoc(N), MVT::i64); @@ -321,19 +321,19 @@ def IsOver48Bits : ImmLeaf; def : Pat< (i64 IsOver16Bits:$src1), - (MOVK_ri (MOVK_ri (MOV_ri IsLess15Bits:$src1), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1) + (MOVK_ri (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1) >; def : Pat< (i64 IsOver32Bits:$src1), - (MOVK_ri (MOVK_ri (MOVK_ri (MOV_ri IsLess15Bits:$src1), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1), IsOver32Bits:$src1, 2) + (MOVK_ri (MOVK_ri (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1), IsOver32Bits:$src1, 2) >; def : Pat< (i64 IsOver48Bits:$src1), - (MOVK_ri (MOVK_ri (MOVK_ri (MOVK_ri (MOV_ri IsLess15Bits:$src1), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1), IsOver32Bits:$src1, 2), IsOver48Bits:$src1, 3) + (MOVK_ri (MOVK_ri (MOVK_ri (MOVK_ri (MOV_ri 0), IsLess16Bits:$src1, 0), IsOver16Bits:$src1, 1), IsOver32Bits:$src1, 2), IsOver48Bits:$src1, 3) >; diff --git a/llvm/lib/Target/XVM/XVMMCInstLower.cpp b/llvm/lib/Target/XVM/XVMMCInstLower.cpp index 6026d5d1a81c..ac58ad2c755b 100644 --- a/llvm/lib/Target/XVM/XVMMCInstLower.cpp +++ b/llvm/lib/Target/XVM/XVMMCInstLower.cpp @@ -12,16 +12,25 @@ //===----------------------------------------------------------------------===// #ifdef XVM_DYLIB_MODE -#include "llvm/CodeGen/AsmPrinter.h" #include "XVMMCInstLower.h" - +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; -MCSymbol *XVMMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { +MCSymbol * +XVMMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { return Printer.getSymbol(MO.getGlobal()); } -MCSymbol *XVMMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const { +MCSymbol * +XVMMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const { return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); } @@ -41,32 +50,33 @@ void XVMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { for (const MachineOperand &MO : MI->operands()) { MCOperand MCOp; switch (MO.getType()) { + default: + MI->print(errs()); + llvm_unreachable("unknown operand type"); + case MachineOperand::MO_Register: + // Ignore all implicit register operands. + if (MO.isImplicit()) + continue; + MCOp = MCOperand::createReg(MO.getReg()); + break; case MachineOperand::MO_Immediate: MCOp = MCOperand::createImm(MO.getImm()); break; - case MachineOperand::MO_GlobalAddress: - MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); - break; case MachineOperand::MO_MachineBasicBlock: - MCOp = MCOperand::createExpr(MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); - break; - case MachineOperand::MO_Register: // Ignore all implicit register operands. - if (MO.isImplicit()) - continue; - MCOp = MCOperand::createReg(MO.getReg()); + MCOp = MCOperand::createExpr( + MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); break; case MachineOperand::MO_RegisterMask: continue; case MachineOperand::MO_ExternalSymbol: MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); break; - default: - MI->print(errs()); - llvm_unreachable("unknown operand type"); + case MachineOperand::MO_GlobalAddress: + MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); + break; } OutMI.addOperand(MCOp); } } - #endif diff --git a/llvm/lib/Target/XVM/XVMRegisterInfo.cpp b/llvm/lib/Target/XVM/XVMRegisterInfo.cpp index 9c08b9efcd8f..4466b1826e31 100644 --- a/llvm/lib/Target/XVM/XVMRegisterInfo.cpp +++ b/llvm/lib/Target/XVM/XVMRegisterInfo.cpp @@ -29,7 +29,6 @@ using namespace llvm; #define XVM_STACK_SIZE_LIMIT 1024 -#define TEMPLATE_INT_32 32 XVMRegisterInfo::XVMRegisterInfo() : XVMGenRegisterInfo(XVM::R0) {} @@ -44,43 +43,44 @@ BitVector XVMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { return Reserved; } -static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL) { - if (Offset <= -XVM_STACK_SIZE_LIMIT) { - const Function &F = MF.getFunction(); - std::ostringstream OSS; - OSS << "Looks like the XVM stack limit of " << XVM_STACK_SIZE_LIMIT << " bytes is exceeded. " - << "Please move large on stack variables into XVM maps.\n"; - std::string StrCopy = OSS.str(); - DiagnosticInfoUnsupported DiagStackSize(F, StrCopy, DL); - F.getContext().diagnose(DiagStackSize); +static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL) +{ + if (Offset <= -512) { + const Function &F = MF.getFunction(); + std::ostringstream OSS; + OSS << "Looks like the XVM stack limit of " << XVM_STACK_SIZE_LIMIT << " bytes is exceeded. " + << "Please move large on stack variables into XVM maps.\n"; + std::string StrCopy = OSS.str(); + DiagnosticInfoUnsupported DiagStackSize(F, StrCopy, DL); + F.getContext().diagnose(DiagStackSize); } } -void XVMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBIterator, - int AdjStackP, unsigned FIOpNum, - RegScavenger *RegScav) const { - assert(AdjStackP == 0 && "Unexpected"); - unsigned counter = 0; - MachineInstr &MInstr = *MBBIterator; - MachineBasicBlock &MBBlock = *MInstr.getParent(); - MachineFunction &MFunction = *MBBlock.getParent(); - DebugLoc DLoc = MInstr.getDebugLoc(); - if (!DLoc) +void XVMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, unsigned FIOperandNum, + RegScavenger *RS) const { + assert(SPAdj == 0 && "Unexpected"); + unsigned i = 0; + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + DebugLoc DL = MI.getDebugLoc(); + if (!DL) /* try harder to get some debug loc */ - for (auto &RetryIterator : MBBlock) - if (RetryIterator.getDebugLoc()) { - DLoc = RetryIterator.getDebugLoc(); + for (auto &I : MBB) + if (I.getDebugLoc()) { + DL = I.getDebugLoc(); break; } - while (!MInstr.getOperand(counter).isFI()) { - ++counter; - assert(counter < MInstr.getNumOperands() && "Instr doesn't have FrameIndex operand!"); + while (!MI.getOperand(i).isFI()) { + ++i; + assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); } - Register FrameReg = getFrameRegister(MFunction); - int FrameIndex = MInstr.getOperand(counter).getIndex(); - const TargetInstrInfo &TII = *MFunction.getSubtarget().getInstrInfo(); + Register FrameReg = getFrameRegister(MF); + int FrameIndex = MI.getOperand(i).getIndex(); + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); /* Offset from frame index are offsets from FP, * which is pointing at current function's stack bottom (larger address) @@ -92,42 +92,42 @@ void XVMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBIterato * it is pointing at (FP - StackSize), and it is fixed during function execution * Therefore, we use SP+(Stacksize + FP_offset) to mimic (FP + FP_offset) */ - auto &MFI = MFunction.getFrameInfo(); + auto &MFI = MF.getFrameInfo(); uint64_t StackSize = MFI.getStackSize(); - if (MInstr.getOpcode() == XVM::MOV_rr) { - int Offset = MFunction.getFrameInfo().getObjectOffset(FrameIndex); - WarnSize(Offset, MFunction, DLoc); - Register reg = MInstr.getOperand(counter - 1).getReg(); - BuildMI(MBBlock, ++MBBIterator, DLoc, TII.get(XVM::MOV_rr), reg).addReg(XVM::SP); + if (MI.getOpcode() == XVM::MOV_rr) { + int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); + WarnSize(Offset, MF, DL); + Register reg = MI.getOperand(i - 1).getReg(); + BuildMI(MBB, ++II, DL, TII.get(XVM::MOV_rr), reg).addReg(XVM::SP); if (StackSize + Offset) { - BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); + BuildMI(MBB, II, DL, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); } - MInstr.eraseFromParent(); + MI.eraseFromParent(); return; } - int Offset = MFunction.getFrameInfo().getObjectOffset(FrameIndex) + - MInstr.getOperand(counter + 1).getImm(); - if (!isInt(Offset)) + int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + + MI.getOperand(i + 1).getImm(); + if (!isInt<32>(Offset)) llvm_unreachable("bug in frame offset"); - WarnSize(Offset, MFunction, DLoc); + WarnSize(Offset, MF, DL); - if (MInstr.getOpcode() == XVM::FI_ri) { + if (MI.getOpcode() == XVM::FI_ri) { // Note: to be tested and modified later // architecture does not really support FI_ri, replace it with // MOV_rr , frame_reg // ADD_ri , imm - Register reg = MInstr.getOperand(counter - 1).getReg(); - BuildMI(MBBlock, ++MBBIterator, DLoc, TII.get(XVM::MOV_rr), reg).addReg(FrameReg); - BuildMI(MBBlock, MBBIterator, DLoc, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); + Register reg = MI.getOperand(i - 1).getReg(); + BuildMI(MBB, ++II, DL, TII.get(XVM::MOV_rr), reg).addReg(FrameReg); + BuildMI(MBB, II, DL, TII.get(XVM::AddRef_ri), reg).addReg(reg).addImm(StackSize + Offset); // Remove FI_ri instruction - MInstr.eraseFromParent(); + MI.eraseFromParent(); } else { - MInstr.getOperand(counter).ChangeToRegister(FrameReg, false); - MInstr.getOperand(counter + 1).ChangeToImmediate(StackSize + Offset); + MI.getOperand(i).ChangeToRegister(FrameReg, false); + MI.getOperand(i + 1).ChangeToImmediate(StackSize + Offset); } } @@ -146,5 +146,4 @@ XVMRegisterInfo::getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const { return CSR_RegMask; } - #endif diff --git a/llvm/lib/Target/XVM/XVMRegisterInfo.h b/llvm/lib/Target/XVM/XVMRegisterInfo.h index ab1b79812745..2a5221d08a11 100644 --- a/llvm/lib/Target/XVM/XVMRegisterInfo.h +++ b/llvm/lib/Target/XVM/XVMRegisterInfo.h @@ -28,9 +28,9 @@ struct XVMRegisterInfo : public XVMGenRegisterInfo { BitVector getReservedRegs(const MachineFunction &MF) const override; - void eliminateFrameIndex(MachineBasicBlock::iterator MInstr, int AdjStackP, + void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, - RegScavenger *RegScav = nullptr) const override; + RegScavenger *RS = nullptr) const override; Register getFrameRegister(const MachineFunction &MF) const override; diff --git a/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp b/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp index 9acd3e0ce9d2..c2462ef33869 100644 --- a/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp +++ b/llvm/lib/Target/XVM/XVMSelectionDAGInfo.cpp @@ -71,5 +71,4 @@ SDValue XVMSelectionDAGInfo::EmitTargetCodeForMemset( } return Op1.getValue(0); } - #endif diff --git a/llvm/lib/Target/XVM/XVMSubtarget.cpp b/llvm/lib/Target/XVM/XVMSubtarget.cpp index ff7b89002d0c..722d55c35e09 100644 --- a/llvm/lib/Target/XVM/XVMSubtarget.cpp +++ b/llvm/lib/Target/XVM/XVMSubtarget.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Host.h" + #define DEBUG_TYPE "xvm-subtarget" #define GET_SUBTARGETINFO_TARGET_DESC diff --git a/llvm/lib/Target/XVM/XVMTargetMachine.cpp b/llvm/lib/Target/XVM/XVMTargetMachine.cpp index f136c1dd3382..f7435f9a193c 100644 --- a/llvm/lib/Target/XVM/XVMTargetMachine.cpp +++ b/llvm/lib/Target/XVM/XVMTargetMachine.cpp @@ -16,17 +16,21 @@ #include "XVM.h" #include "XVMTargetTransformInfo.h" #include "MCTargetDesc/XVMMCAsmInfo.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "TargetInfo/XVMTargetInfo.h" -#include "llvm/Transforms/Scalar.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/PassManager.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Scalar/SimplifyCFG.h" +#include "llvm/Transforms/Utils/SimplifyCFGOptions.h" #include "llvm/Transforms/Utils.h" -#include "llvm/Transforms/Scalar/DeadStoreElimination.h" -#include "llvm/InitializePasses.h" -#include "llvm/Transforms/Scalar/GVN.h" -#include "llvm/Transforms/Vectorize.h" -#include "llvm/Transforms/IPO.h" using namespace llvm; @@ -41,8 +45,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTarget() { initializeXVMCFGStackifyPass(PR); initializeXVMCFGStructurePass(PR); initializeXVMUpdateRefInstrForMIPass(PR); - initializeDSELegacyPassPass(PR); - initializeJumpThreadingPass(PR); } extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXVMTargetCalledInDylib() { @@ -60,21 +62,20 @@ static Reloc::Model getEffectiveRelocModel(Optional RM) { return RM.value_or(Reloc::PIC_); } -XVMTargetMachine::XVMTargetMachine(const Target &Target, const Triple &TTriple, - StringRef Core, StringRef FString, +XVMTargetMachine::XVMTargetMachine(const Target &T, const Triple &TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, - Optional RelocMdl, - Optional CodeMdl, - CodeGenOpt::Level OptLvl, bool JustInTime) - : LLVMTargetMachine(Target, computeDataLayout(TTriple), - TTriple, Core, FString, Options, - getEffectiveRelocModel(RelocMdl), - getEffectiveCodeModel(CodeMdl, CodeModel::Small), - OptLvl), - TLOF(std::make_unique()), - Subtarget(TTriple, std::string(Core), std::string(FString), *this) { + Optional RM, + Optional CM, + CodeGenOpt::Level OL, bool JIT) + : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, + getEffectiveRelocModel(RM), + getEffectiveCodeModel(CM, CodeModel::Small), OL), + TLOF(std::make_unique()), + Subtarget(TT, std::string(CPU), std::string(FS), *this) { initAsmInfo(); this->Options.EmitAddrsig = false; + setRequiresStructuredCFG(true); } @@ -100,10 +101,6 @@ public: bool XVMPassConfig::addPreISel() { addPass(createFlattenCFGPass()); addPass(createFixIrreduciblePass()); - addPass(createDeadStoreEliminationPass()); - addPass(createJumpThreadingPass(-1)); - addPass(createSpeculativeExecutionPass()); - addPass(createMergedLoadStoreMotionPass()); return false; } diff --git a/llvm/lib/Target/XVM/XVMTargetMachine.h b/llvm/lib/Target/XVM/XVMTargetMachine.h index 6d4146c29b19..3b25b0f1e89a 100644 --- a/llvm/lib/Target/XVM/XVMTargetMachine.h +++ b/llvm/lib/Target/XVM/XVMTargetMachine.h @@ -22,10 +22,10 @@ class XVMTargetMachine : public LLVMTargetMachine { XVMSubtarget Subtarget; public: - XVMTargetMachine(const Target &Target, const Triple &TTriple, - StringRef Core, StringRef FString, const TargetOptions &Options, - Optional RelocMdl, Optional CodeMdl, - CodeGenOpt::Level OptLvl, bool JustInTime); + XVMTargetMachine(const Target &T, const Triple &TT, StringRef CPU, + StringRef FS, const TargetOptions &Options, + Optional RM, Optional CM, + CodeGenOpt::Level OL, bool JIT); const XVMSubtarget *getSubtargetImpl() const { return &Subtarget; } const XVMSubtarget *getSubtargetImpl(const Function &) const override { diff --git a/llvm/lib/Target/XVM/XVMTargetTransformInfo.h b/llvm/lib/Target/XVM/XVMTargetTransformInfo.h index ecf6960157c9..2194866b6ab0 100644 --- a/llvm/lib/Target/XVM/XVMTargetTransformInfo.h +++ b/llvm/lib/Target/XVM/XVMTargetTransformInfo.h @@ -20,7 +20,6 @@ #include "llvm/CodeGen/BasicTTIImpl.h" #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h" -#define TEMPLATE_INT_32 32 namespace llvm { class XVMTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase BaseT; @@ -39,7 +38,7 @@ public: TLI(ST->getTargetLowering()) {} int getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) { - if (Imm.getBitWidth() <= 64 && isInt(Imm.getSExtValue())) + if (Imm.getBitWidth() <= 64 && isInt<32>(Imm.getSExtValue())) return TTI::TCC_Free; return TTI::TCC_Basic; @@ -57,11 +56,11 @@ public: } InstructionCost getArithmeticInstrCost( - unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, - TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue, - TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, - TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, - TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, + unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, + TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue, + TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, + TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, + TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, ArrayRef Args = ArrayRef(), const Instruction *CxtI = nullptr) { int ISD = TLI->InstructionOpcodeToISD(Opcode); diff --git a/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp b/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp index 4838884ca14d..11bdb0aad565 100644 --- a/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp +++ b/llvm/lib/Target/XVM/XVMUpdateRefInstrForMI.cpp @@ -4,7 +4,6 @@ #include "XVM_def.h" #include "XVMInstrInfo.h" #include "XVMTargetMachine.h" -#include "XVMErrorMsg.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "MCTargetDesc/XVMInstPrinter.h" @@ -17,27 +16,6 @@ using namespace llvm; #define XVM_REF_DETERMINE_NAME "XVM pseudo instruction ref determine pass" #define XVM_SYM_REG_NON_REF 0b00000000 #define XVM_SYM_REG_REF 0b00000001 -#define XVM_MAX_NUM_PARAM 5 -#define SRET_REG_NUM 6 -#define NUM_MO_2 2 -#define NUM_MO_3 3 - -#define MO_FIRST 0 -#define MO_SECOND 1 -#define MO_THIRD 2 -#define MAX_IMM 8191 - -/** mov rd #simm (16 bits) - * movk rd, #uimm (16 bits), #shift (0:no 1:16bits 2:32bits 3:48bits) - * addref rd, rn, #uimm (14bits) - */ -#define NUM_OF_IMM_BITS_ADDREF 14 -#define NUM_OF_IMM_BITS_MOV 16 -#define NUM_OF_IMM_BITS_MOVK1 32 -#define NUM_OF_IMM_BITS_MOVK2 48 - -#define NUM_MO_PER_PHI_BRANCH 2 -#define INIT_SMALL_VECTOR_SIZE 4 namespace { class XVMUpdateRefInstrForMI : public MachineFunctionPass { @@ -50,69 +28,17 @@ public: bool runOnMachineFunction(MachineFunction &MF) override; StringRef getPassName() const override { return XVM_REF_DETERMINE_NAME; } private: - bool scanRefInfoInMBB(MachineBasicBlock &MBB); - bool updateRefInfoBasedInMBB(MachineBasicBlock &MBB); - - bool checkAndUpdateOrInMBB(MachineBasicBlock &MBB); + bool updateRefInfoInMBB(MachineBasicBlock &MBB); void updatePtrRefInMBB(MachineBasicBlock &MBB); - void doubleCheckPhiMIWithRef(MachineBasicBlock &MBB); - void doubleCheckRefs(MachineBasicBlock &MBB); - bool updateRegistersOfMIInMBB(MachineBasicBlock &MBB); - bool finalFixRefs(void); void FindNonRefRegInFunc(const MachineFunction &MF); }; char XVMUpdateRefInstrForMI::ID = 0; } -static std::map MapMIToBeFixed; static std::map MapRefRegInFunc; static std::map MapPtrRegInFunc; static std::set SetNonRefRegInFunc; -static bool IsValidRefOpCode(unsigned OpCode) { - switch (OpCode) { - case XVM::ADD_ri: - case XVM::ADD_rr: - case XVM::SUB_ri: - case XVM::SUB_rr: - case XVM::OR_ri: - case XVM::OR_rr: - case XVM::XOR_ri: - case XVM::XOR_rr: - case XVM::AND_ri: - case XVM::AND_rr: - case XVM::STW: - case XVM::STH: - case XVM::STB: - case XVM::STD: - case XVM::LDW_z: - case XVM::LDH_z: - case XVM::LDB_z: - case XVM::LDW: - case XVM::LDH: - case XVM::LDB: - case XVM::LDD: - case XVM::MOV_rr: - return true; - default: - return false; - } -} - -static inline void SetRegTypeForMO(MachineOperand &MO, unsigned char RegType) { - if (MO.isReg()) { - Register regNo = MO.getReg(); - std::map::iterator I = MapRefRegInFunc.find(regNo); - if (I == MapRefRegInFunc.end()) { - MapRefRegInFunc.insert(std::pair(regNo, RegType)); - } else { - if (IsValidRefOpCode(MO.getParent()->getOpcode())) { - MapRefRegInFunc[regNo] = MapRefRegInFunc[regNo] | RegType; - } - } - } -} - static void CheckFunctionReturn(Function &F) { Type *Ty = F.getReturnType(); /* Return is always r0 for xvm */ @@ -128,28 +54,28 @@ static void CheckFunctionReturn(Function &F) { } static Register inline getPhysicalRegister(unsigned index) { - switch (index) { - case 0: return XVM::R0; - case 1: return XVM::R1; - case 2: return XVM::R2; - case 3: return XVM::R3; - case 4: return XVM::R4; - case 5: return XVM::R5; - case 6: return XVM::R6; - case 7: return XVM::R7; - case 8: return XVM::R8; - case 9: return XVM::R9; - case 10: return XVM::R10; - case 11: return XVM::R11; - case 12: return XVM::R12; - case 13: return XVM::R13; - case 14: return XVM::R14; - case 15: return XVM::R15; - case 16: return XVM::R16; - case 17: return XVM::R17; - default: - llvm_unreachable("Invalid physical register index"); - } + switch (index) { + case 0: return XVM::R0; + case 1: return XVM::R1; + case 2: return XVM::R2; + case 3: return XVM::R3; + case 4: return XVM::R4; + case 5: return XVM::R5; + case 6: return XVM::R6; + case 7: return XVM::R7; + case 8: return XVM::R8; + case 9: return XVM::R9; + case 10: return XVM::R10; + case 11: return XVM::R11; + case 12: return XVM::R12; + case 13: return XVM::R13; + case 14: return XVM::R14; + case 15: return XVM::R15; + case 16: return XVM::R16; + case 17: return XVM::R17; + default: + llvm_unreachable("Invalid physical register index"); + } } static void CheckFunctionArgs(Function &F) { @@ -159,56 +85,55 @@ static void CheckFunctionArgs(Function &F) { * it is handled with check/update steps followed. */ for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - if (idx > XVM_MAX_NUM_PARAM) { + if (idx > 5) { break; } Type *Ty = I->getType(); std::string regName = "r" + itostr(idx); if (auto *PTy = dyn_cast(Ty)) { - LLVM_DEBUG(dbgs() << "arg[" << idx << "]=" << I->getName().data() << " is ref.\n"); + LLVM_DEBUG(dbgs() << "arg[" << idx << "]=" << I->getName().data() << ' is ref.\n'); if (!I->hasAttribute(Attribute::StructRet)) { MapRefRegInFunc.insert(std::pair(getPhysicalRegister(idx), XVM_SYM_REG_REF)); } else { // R6 is used to pass the sret return - MapRefRegInFunc.insert(std::pair(getPhysicalRegister(SRET_REG_NUM), - XVM_SYM_REG_REF)); + MapRefRegInFunc.insert(std::pair(getPhysicalRegister(6), XVM_SYM_REG_REF)); } } else if (Ty->isIntegerTy()) { MapRefRegInFunc.insert(std::pair(getPhysicalRegister(idx), XVM_SYM_REG_NON_REF)); - LLVM_DEBUG(dbgs() << "arg[" << idx << "]=" << I->getName().data() << " is not ref.\n"); + LLVM_DEBUG(dbgs() << "arg[" << idx << "]=" << I->getName().data() << ' is not ref.\n'); } else { - LLVM_DEBUG(dbgs() << "XVM Error: Invalid param type"); + llvm_unreachable("Invalid param type"); } idx++; } } static void setRefFlagFor2Ops(MachineOperand &MO_def, MachineOperand &MO_use) { - /* verify def */ - if (MO_def.isReg()) { - if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { - llvm_unreachable("unhandled Operand!!"); - } - } - /* check use */ - if (MO_use.isReg()) { - if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { - llvm_unreachable("unhandled Operand!!"); + /* verify def */ + if (MO_def.isReg()) { + if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { + llvm_unreachable("unhandled Operand!!"); + } } - Register regNo = MO_use.getReg(); - std::map::iterator I = MapRefRegInFunc.find(regNo); - if (I == MapRefRegInFunc.end()) { - SetRegTypeForMO(MO_def, XVM_SYM_REG_NON_REF); - } else { - SetRegTypeForMO(MO_def, I->second); + /* check use */ + if (MO_use.isReg()) { + if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { + llvm_unreachable("unhandled Operand!!"); + } + Register regNo = MO_use.getReg(); + std::map::iterator I = MapRefRegInFunc.find(regNo); + if (I == MapRefRegInFunc.end()) { + MapRefRegInFunc.insert(std::pair(MO_def.getReg(), XVM_SYM_REG_NON_REF)); + } else { + MapRefRegInFunc.insert(std::pair(MO_def.getReg(), I->second)); + } } - } } static inline void updateRefMapForRefInst(MachineOperand &MO_use, unsigned char flag) { std::map::iterator I1 = MapRefRegInFunc.find(MO_use.getReg()); if (I1 == MapRefRegInFunc.end()) { - SetRegTypeForMO(MO_use, flag); + MapRefRegInFunc.insert(std::pair(MO_use.getReg(), flag)); } else I1->second = flag; @@ -216,9 +141,9 @@ static inline void updateRefMapForRefInst(MachineOperand &MO_use, unsigned char static void checkSimpleMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::COPY) { - assert(MI.getNumOperands() == NUM_MO_2); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 2); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); setRefFlagFor2Ops(MO_def, MO_use); } } @@ -230,18 +155,15 @@ static bool updateCopyMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { static void checkMovMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::MOV_rr) { - assert(MI.getNumOperands() == NUM_MO_2); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 2); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); setRefFlagFor2Ops(MO_def, MO_use); - if (MO_use.isFI()) { - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - } } if (MI.getOpcode() == XVM::MOV_ri) { - assert(MI.getNumOperands() == NUM_MO_2); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - SetRegTypeForMO(MO_def, XVM_SYM_REG_NON_REF); + assert(MI.getNumOperands() == 2); + MachineOperand &MO_def = MI.getOperand(0); + MapRefRegInFunc.insert(std::pair(MO_def.getReg(), XVM_SYM_REG_NON_REF)); } } @@ -254,49 +176,49 @@ static void checkLoadMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::LDB || MI.getOpcode() == XVM::LDH || MI.getOpcode() == XVM::LDW || MI.getOpcode() == XVM::LDB_z || MI.getOpcode() == XVM::LDH_z || MI.getOpcode() == XVM::LDW_z || MI.getOpcode() == XVM::LDD) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); /* verify def */ if (MO_def.isReg()) { - if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { - llvm_unreachable("unhandled Operand!!"); - } + if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { + llvm_unreachable("unhandled Operand!!"); + } } /* check use */ if (MO_use.isReg()) { - if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { - llvm_unreachable("unhandled Operand!!"); - } - // always be ref - SetRegTypeForMO(MO_use, XVM_SYM_REG_REF); + if (!MO_def.isDef() && !MO_def.isImplicit() && !MO_def.isKill()) { + llvm_unreachable("unhandled Operand!!"); + } + // always be ref + MapRefRegInFunc.insert(std::pair(MO_use.getReg(), XVM_SYM_REG_REF)); } } if (MI.getOpcode() == XVM::LD_global_imm64) { - assert(MI.getNumOperands() == NUM_MO_2); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 2); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); if (MO_use.isGlobal()) { - LLVM_DEBUG(dbgs() << "Global:" << MO_use.getGlobal()->getName().data() << " to load.\n"); - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); + LLVM_DEBUG(dbgs() << "Global:" << MO_use.getGlobal()->getName().data() << ' to load.\n'); + MapRefRegInFunc.insert(std::pair(MO_def.getReg(), XVM_SYM_REG_REF)); } } } static bool updateLoadMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { if (MI.getOpcode() == XVM::LDD) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be ldrref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - MI.setDesc(TII->get(XVM::LoadRef_ri)); - return true; - } + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + MI.setDesc(TII->get(XVM::LoadRef_ri)); + return true; + } } } return false; @@ -305,9 +227,9 @@ static bool updateLoadMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { static void checkAddSubMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::ADD_ri || MI.getOpcode() == XVM::ADD_rr || MI.getOpcode() == XVM::SUB_ri || MI.getOpcode() == XVM::SUB_rr) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); setRefFlagFor2Ops(MO_def, MO_use); return; } @@ -317,48 +239,33 @@ static void checkOrXorAndMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::OR_ri || MI.getOpcode() == XVM::XOR_ri|| MI.getOpcode() == XVM::AND_ri) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); setRefFlagFor2Ops(MO_def, MO_use); return; } if (MI.getOpcode() == XVM::OR_rr || MI.getOpcode() == XVM::XOR_rr|| MI.getOpcode() == XVM::AND_rr) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - Register regNo1 = MO_use.getReg(); - Register regNo2 = MO_use2.getReg(); - std::map::iterator I1 = MapRefRegInFunc.find(regNo1); - std::map::iterator I2 = MapRefRegInFunc.find(regNo2); - if (I1 != MapRefRegInFunc.end() && I1->second == XVM_SYM_REG_REF) { - if (I2 != MapRefRegInFunc.end() && I2->second == XVM_SYM_REG_REF) { - ; - } else { - setRefFlagFor2Ops(MO_def, MO_use); - } - } else { - if (I2 != MapRefRegInFunc.end() && I2->second == XVM_SYM_REG_REF) { - setRefFlagFor2Ops(MO_def, MO_use); - setRefFlagFor2Ops(MO_def, MO_use2); - } else { - ; - } - } + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); + setRefFlagFor2Ops(MO_def, MO_use); + // MO_use2 should not be ref; + MachineOperand &MO_use2 = MI.getOperand(2); + updateRefMapForRefInst(MO_use2, XVM_SYM_REG_NON_REF); return; } } static inline bool updateAddSubWithSubAddForImm(MachineInstr &MI, const XVMInstrInfo *TII) { if (MI.getOpcode() == XVM::ADD_ri || MI.getOpcode() == XVM::SUB_ri) { - assert(MI.getOperand(MO_THIRD).isImm()); - int64_t imm = MI.getOperand(MO_THIRD).getImm(); + assert(MI.getOperand(2).isImm()); + int64_t imm = MI.getOperand(2).getImm(); if (imm < 0) { imm = -imm; - MI.getOperand(MO_THIRD).setImm(imm); + MI.getOperand(2).setImm(imm); if (MI.getOpcode() == XVM::ADD_ri) { MI.setDesc(TII->get(XVM::SUB_ri)); return true; @@ -372,11 +279,11 @@ static inline bool updateAddSubWithSubAddForImm(MachineInstr &MI, const XVMInstr } static inline void updateAddRiWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getOperand(MO_THIRD).isImm()); - int64_t imm = MI.getOperand(MO_THIRD).getImm(); + assert(MI.getOperand(2).isImm()); + int64_t imm = MI.getOperand(2).getImm(); if (imm < 0) { imm = -imm; - MI.getOperand(MO_THIRD).setImm(imm); + MI.getOperand(2).setImm(imm); MI.setDesc(TII->get(XVM::SubRef_ri)); } else { MI.setDesc(TII->get(XVM::AddRef_ri)); @@ -384,62 +291,27 @@ static inline void updateAddRiWithRef(MachineInstr &MI, const XVMInstrInfo *TII) } static inline bool updateAddMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be addref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); // Update instr if MO_def is ref if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - // Update MO_use1 to be ref if MO_def is ref - if (MI.getOpcode() == XVM::ADD_ri) { - updateRefMapForRefInst(MO_use1, XVM_SYM_REG_REF); + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + // Update MO_use to be ref if MO_def is ref + updateRefMapForRefInst(MO_use, XVM_SYM_REG_REF); + if (MI.getOpcode() == XVM::ADD_ri) updateAddRiWithRef(MI, TII); - } else { - // It may be the case there use2 is a ref while use1 is not a ref - MachineOperand &MO_use2 = MI.getOperand(2); - Register regNoUse1 = MO_use1.getReg(); - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator ItrUse1 = MapRefRegInFunc.find(regNoUse1); - std::map::iterator ItrUse2 = MapRefRegInFunc.find(regNoUse2); - if (ItrUse2 != MapRefRegInFunc.end()) { - if (ItrUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - // Now Use2 is a ref: we need to Switch Operand1 and Operand2 - updateRefMapForRefInst(MO_use1, XVM_SYM_REG_NON_REF); - - // by create a new MI - MachineBasicBlock::iterator II = MI.getIterator(); - MachineBasicBlock &MBB = *MI.getParent(); - MachineFunction *MF = MBB.getParent(); - DebugLoc DL = MI.getDebugLoc(); - MachineRegisterInfo &MRI = MF->getRegInfo(); - MachineInstr *ReplaceMI = BuildMI(MBB, II, DL, TII->get(XVM::AddRef_rr)); - - MachineOperand &MO_def = MI.getOperand(0); - MachineOperand &MO_use1 = MI.getOperand(1); - MachineOperand &MO_use2 = MI.getOperand(2); - - ReplaceMI->addOperand(MO_def); - ReplaceMI->addOperand(MO_use2); - ReplaceMI->addOperand(MO_use1); - MBB.remove_instr(&MI); - MRI.verifyUseLists(); - } else { - // Now Use2 is not ref, then Use1 should be ref - updateRefMapForRefInst(MO_use1, XVM_SYM_REG_REF); - MI.setDesc(TII->get(XVM::AddRef_rr)); - } - } - } + else + MI.setDesc(TII->get(XVM::AddRef_rr)); return true; - } + } } - // Update instr if MO_use1 if ref - regNo = MO_use1.getReg(); + // Update instr if MO_use if ref + regNo = MO_use.getReg(); I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { if (I->second == XVM_SYM_REG_REF && @@ -455,65 +327,50 @@ static inline bool updateAddMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) } static inline bool updateSubriMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be subref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - updateRefMapForRefInst(MO_use, XVM_SYM_REG_REF); - if (MI.getOpcode() == XVM::SUB_ri) - MI.setDesc(TII->get(XVM::SubRef_ri)); - else - MI.setDesc(TII->get(XVM::SubRef_rr)); - return true; - } + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + updateRefMapForRefInst(MO_use, XVM_SYM_REG_REF); + if (MI.getOpcode() == XVM::SUB_ri) + MI.setDesc(TII->get(XVM::SubRef_ri)); + else + MI.setDesc(TII->get(XVM::SubRef_rr)); + return true; + } } regNo = MO_use.getReg(); I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - if (MI.getOpcode() == XVM::SUB_ri) - MI.setDesc(TII->get(XVM::SubRef_ri)); - else - MI.setDesc(TII->get(XVM::SubRef_rr)); - return true; - } + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + if (MI.getOpcode() == XVM::SUB_ri) + MI.setDesc(TII->get(XVM::SubRef_ri)); + else + MI.setDesc(TII->get(XVM::SubRef_rr)); + return true; + } } return false; } static inline bool updateSubrrMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use1 = MI.getOperand(1); + MachineOperand &MO_use2 = MI.getOperand(2); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be subref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - updateRefMapForRefInst(MO_use1, XVM_SYM_REG_REF); - I = MapRefRegInFunc.find(MO_use2.getReg()); - if (I != MapRefRegInFunc.end() && I->second == XVM_SYM_REG_REF) { - MI.setDesc(TII->get(XVM::DifRef_rr)); - } else { - MI.setDesc(TII->get(XVM::SubRef_rr)); - } - return true; - } - } - regNo = MO_use1.getReg(); - I = MapRefRegInFunc.find(regNo); - if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - if (MO_use2.isReg()) { + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + updateRefMapForRefInst(MO_use1, XVM_SYM_REG_REF); I = MapRefRegInFunc.find(MO_use2.getReg()); if (I != MapRefRegInFunc.end() && I->second == XVM_SYM_REG_REF) { MI.setDesc(TII->get(XVM::DifRef_rr)); @@ -522,10 +379,27 @@ static inline bool updateSubrrMIWithRef(MachineInstr &MI, const XVMInstrInfo *TI } return true; } + } + regNo = MO_use1.getReg(); + I = MapRefRegInFunc.find(regNo); + if (I != MapRefRegInFunc.end()) { + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + if (MO_use2.isReg()) { + I = MapRefRegInFunc.find(MO_use2.getReg()); + if (I != MapRefRegInFunc.end() && I->second == XVM_SYM_REG_REF) { + MI.setDesc(TII->get(XVM::DifRef_rr)); + } else { + MI.setDesc(TII->get(XVM::SubRef_rr)); + } + return true; + } } } return false; } + // Update add/sub with sub/add if negative imm + static bool updateAddSubMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { bool Modified = false; @@ -544,168 +418,126 @@ static bool updateAddSubMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { } } -static inline bool switchOperandUse1Use2(MachineBasicBlock &MBB, MachineInstr &MI, const XVMInstrInfo *TII) { - // we have cases where use1 is not ref while use2 is ref - if (MI.getOpcode() == XVM::OrRef_rr || - MI.getOpcode() == XVM::XorRef_rr || - MI.getOpcode() == XVM::AndRef_rr) { - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - Register regNo = MO_use2.getReg(); - std::map::iterator I = MapRefRegInFunc.find(regNo); - if (I != MapRefRegInFunc.end() && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF) { - // MO_def has to be ref - updateRefMapForRefInst(MO_def, XVM_SYM_REG_REF); - // we need to Switch the order of use1 and use2 - MachineBasicBlock::iterator II = MI.getIterator(); - MachineFunction *MF = MBB.getParent(); - DebugLoc DL = MI.getDebugLoc(); - MachineRegisterInfo &MRI = MF->getRegInfo(); - MachineInstr *ReplaceMI = BuildMI(MBB, II, DL, TII->get(MI.getOpcode())); - - MachineOperand &NewMO_def = MI.getOperand(0); - MachineOperand &NewMO_use1 = MI.getOperand(1); - MachineOperand &NewMO_use2 = MI.getOperand(2); - - ReplaceMI->addOperand(NewMO_def); - ReplaceMI->addOperand(NewMO_use2); - ReplaceMI->addOperand(NewMO_use1); - MBB.remove_instr(&MI); - MRI.verifyUseLists(); - return true; - } - } - } -} - -static inline bool updateOrMIWithRef(MachineBasicBlock &MBB, MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); +static inline bool updateOrMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be orref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); // Update instr if MO_def is ref if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - if (MI.getOpcode() == XVM::OR_ri) - MI.setDesc(TII->get(XVM::OrRef_ri)); - else { - MI.setDesc(TII->get(XVM::OrRef_rr)); - switchOperandUse1Use2(MBB, MI, TII); + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + // Update MO_use to be ref if MO_def is ref + updateRefMapForRefInst(MO_use, XVM_SYM_REG_REF); + if (MI.getOpcode() == XVM::OR_ri) + MI.setDesc(TII->get(XVM::OrRef_ri)); + else + MI.setDesc(TII->get(XVM::OrRef_rr)); + return true; } - return true; - } } // Update instr if MO_use if ref regNo = MO_use.getReg(); I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - // MO_def has to be ref - updateRefMapForRefInst(MO_def, XVM_SYM_REG_REF); - if (MI.getOpcode() == XVM::OR_ri) - MI.setDesc(TII->get(XVM::OrRef_ri)); - else - MI.setDesc(TII->get(XVM::OrRef_rr)); - return true; - } + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + if (MI.getOpcode() == XVM::OR_ri) + MI.setDesc(TII->get(XVM::OrRef_ri)); + else + MI.setDesc(TII->get(XVM::OrRef_rr)); + return true; + } } return false; } -static inline bool updateXorMIWithRef(MachineBasicBlock &MBB, MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); +static inline bool updateXorMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be xorref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); // Update instr if MO_def is ref if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - if (MI.getOpcode() == XVM::XOR_ri) - MI.setDesc(TII->get(XVM::XorRef_ri)); - else { - MI.setDesc(TII->get(XVM::XorRef_rr)); - switchOperandUse1Use2(MBB, MI, TII); + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + // Update MO_use to be ref if MO_def is ref + updateRefMapForRefInst(MO_use, XVM_SYM_REG_REF); + if (MI.getOpcode() == XVM::XOR_ri) + MI.setDesc(TII->get(XVM::XorRef_ri)); + else + MI.setDesc(TII->get(XVM::XorRef_rr)); + return true; } - return true; - } } // Update instr if MO_use if ref regNo = MO_use.getReg(); I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end() && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { if (I->second == XVM_SYM_REG_REF) { - // MO_def has to be ref - updateRefMapForRefInst(MO_def, XVM_SYM_REG_REF); - if (MI.getOpcode() == XVM::XOR_ri) - MI.setDesc(TII->get(XVM::XorRef_ri)); - else - MI.setDesc(TII->get(XVM::XorRef_rr)); - return true; - } + if (MI.getOpcode() == XVM::XOR_ri) + MI.setDesc(TII->get(XVM::XorRef_ri)); + else + MI.setDesc(TII->get(XVM::XorRef_rr)); + return true; + } } return false; } -static inline bool updateAndMIWithRef(MachineBasicBlock &MBB, MachineInstr &MI, const XVMInstrInfo *TII) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); +static inline bool updateAndMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { + assert(MI.getNumOperands() == 3); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); /* if MO_def is a ref (it is determined when it is used somewhere), then it should be andref */ Register regNo = MO_def.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); // Update instr if MO_def is ref if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - if (MI.getOpcode() == XVM::AND_ri) - MI.setDesc(TII->get(XVM::AndRef_ri)); - else { - MI.setDesc(TII->get(XVM::AndRef_rr)); - switchOperandUse1Use2(MBB, MI, TII); + if (I->second == XVM_SYM_REG_REF && + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + // Update MO_use to be ref if MO_def is ref + updateRefMapForRefInst(MO_use, XVM_SYM_REG_REF); + if (MI.getOpcode() == XVM::AND_ri) + MI.setDesc(TII->get(XVM::AndRef_ri)); + else + MI.setDesc(TII->get(XVM::AndRef_rr)); + return true; } - return true; - } } - // Update instr if MO_use is ref + // Update instr if MO_use if ref regNo = MO_use.getReg(); I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end() && - SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { + SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { if (I->second == XVM_SYM_REG_REF) { - // MO_def has to be ref - updateRefMapForRefInst(MO_def, XVM_SYM_REG_REF); - if (MI.getOpcode() == XVM::AND_ri) - MI.setDesc(TII->get(XVM::AndRef_ri)); - else - MI.setDesc(TII->get(XVM::AndRef_rr)); - return true; - } + if (MI.getOpcode() == XVM::AND_ri) + MI.setDesc(TII->get(XVM::AndRef_ri)); + else + MI.setDesc(TII->get(XVM::AndRef_rr)); + return true; + } } return false; } -static bool updateOrXorAndMIWithRef(MachineBasicBlock &MBB, MachineInstr &MI, const XVMInstrInfo *TII) { - switch (MI.getOpcode()) { +static bool updateOrXorAndMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { + switch (MI.getOpcode()) + { case XVM::OR_ri: case XVM::OR_rr: - return updateOrMIWithRef(MBB, MI, TII); + return updateOrMIWithRef(MI, TII); case XVM::XOR_ri: case XVM::XOR_rr: - return updateXorMIWithRef(MBB, MI, TII); + return updateXorMIWithRef(MI, TII); case XVM::AND_ri: case XVM::AND_rr: - return updateAndMIWithRef(MBB, MI, TII); + return updateAndMIWithRef(MI, TII); default: return false; } @@ -713,6 +545,14 @@ static bool updateOrXorAndMIWithRef(MachineBasicBlock &MBB, MachineInstr &MI, co static std::map MORegReplaceMap; static std::set MachineInstrExceptionSet; +/** mov rd #simm (16 bits) + * movk rd, #uimm (16 bits), #shift (0:no 1:16bits 2:32bits 3:48bits) + * addref rd, rn, #uimm (14bits) + */ +#define NUM_OF_IMM_BITS_ADDREF 14 +#define NUM_OF_IMM_BITS_MOV 16 +#define NUM_OF_IMM_BITS_MOVK1 32 +#define NUM_OF_IMM_BITS_MOVK2 48 static void handleOffsetWithInstr(MachineInstr &MI, const char *GlobalName) { uint64_t SubSecOffset = GetSubSecOffsetForGlobal(GlobalName); @@ -729,112 +569,96 @@ static void handleOffsetWithInstr(MachineInstr &MI, const char *GlobalName) { /* Addref */ Register VRegForAddref = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *AddrefMI = BuildMI(MB, ++II, DL, TII->get(XVM::AddRef_ri), VRegForAddref) - .addReg(MO_def.getReg()).addImm(SubSecOffset); + .addReg(MO_def.getReg()).addImm(SubSecOffset); MachineInstrExceptionSet.insert(AddrefMI); - MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(MO_FIRST))); + MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(0))); } else if (SubSecOffset < ((1 << NUM_OF_IMM_BITS_MOV) -1)) { /* Mov */ Register VRegForMov = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov).addImm(0); + MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov) + .addImm(SubSecOffset); MachineInstrExceptionSet.insert(MovMI); - /* Movk */ - Register VRegForMovk = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *MovkMI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk) - .addReg(VRegForMov).addImm(SubSecOffset).addImm(MOVK_SHIFT_0); - MachineInstrExceptionSet.insert(MovkMI); /* Addref */ Register VRegForAddref = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *AddrefMI = BuildMI(MB, II, DL, TII->get(XVM::AddRef_rr), VRegForAddref) - .addReg(MO_def.getReg()).addReg(VRegForMovk); + .addReg(MO_def.getReg()).addReg(VRegForMov); MachineInstrExceptionSet.insert(AddrefMI); - MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(MO_FIRST))); + MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(0))); } else if (SubSecOffset < ((1UL << NUM_OF_IMM_BITS_MOVK1) -1)) { /* Mov */ + unsigned int imm1 = SubSecOffset & 0X000000000000FFFF; Register VRegForMov = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov).addImm(0); + MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov) + .addImm(imm1); MachineInstrExceptionSet.insert(MovMI); /* Movk */ - unsigned int imm1 = SubSecOffset & 0X000000000000FFFF; - Register VRegForMovk0 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *Movk0MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk0) - .addReg(VRegForMov).addImm(imm1).addImm(MOVK_SHIFT_0); - MachineInstrExceptionSet.insert(Movk0MI); - /* Movk */ - unsigned int imm2 = (SubSecOffset & 0X00000000FFFF0000) >> NUM_OF_IMM_BITS_MOV; + unsigned int imm2 = (SubSecOffset & 0X00000000FFFF0000)>>16; Register VRegForMovk1 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *Movk1MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk1) - .addReg(VRegForMovk0).addImm(imm2).addImm(MOVK_SHIFT_16); - MachineInstrExceptionSet.insert(Movk1MI); + MachineInstr *MovkMI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk1) + .addReg(VRegForMov).addImm(imm2).addImm(1); + MachineInstrExceptionSet.insert(MovkMI); /* Addref only*/ Register VRegForAddref = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *AddrefMI = BuildMI(MB, II, DL, TII->get(XVM::AddRef_rr), VRegForAddref) - .addReg(MO_def.getReg()).addReg(VRegForMovk1); + .addReg(MO_def.getReg()).addReg(VRegForMovk1); MachineInstrExceptionSet.insert(AddrefMI); - MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(MO_FIRST))); + MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(0))); } else if (SubSecOffset < ((1UL << NUM_OF_IMM_BITS_MOVK2) -1)) { /* Mov */ + unsigned int imm1 = SubSecOffset & 0X000000000000FFFF; Register VRegForMov = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov).addImm(0); + MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov) + .addImm(imm1); MachineInstrExceptionSet.insert(MovMI); /* Movk */ - unsigned int imm1 = SubSecOffset & 0X000000000000FFFF; - Register VRegForMovk0 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *MovkMIk0 = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk0) - .addReg(VRegForMov).addImm(imm1).addImm(MOVK_SHIFT_0); - MachineInstrExceptionSet.insert(MovkMIk0); - /* Movk */ - unsigned int imm2 = (SubSecOffset & 0X00000000FFFF0000) >> NUM_OF_IMM_BITS_MOV; + unsigned int imm2 = (SubSecOffset & 0X00000000FFFF0000)>>16; Register VRegForMovk1 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *Movk1MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk1) - .addReg(VRegForMovk0).addImm(imm2).addImm(MOVK_SHIFT_16); + .addReg(VRegForMov).addImm(imm2).addImm(1); MachineInstrExceptionSet.insert(Movk1MI); /* Movk */ - unsigned int imm3 = (SubSecOffset & 0X0000FFFF00000000) >> NUM_OF_IMM_BITS_MOVK1; + unsigned int imm3 = (SubSecOffset & 0X0000FFFF00000000)>>32; Register VRegForMovk2 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *Movk2MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk2) - .addReg(VRegForMovk1).addImm(imm3).addImm(MOVK_SHIFT_32); + .addReg(VRegForMovk1).addImm(imm3).addImm(2); MachineInstrExceptionSet.insert(Movk2MI); /* Addref only*/ Register VRegForAddref = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *AddrefMI = BuildMI(MB, II, DL, TII->get(XVM::AddRef_rr), VRegForAddref) - .addReg(MO_def.getReg()).addReg(VRegForMovk2); + .addReg(MO_def.getReg()).addReg(VRegForMovk2); MachineInstrExceptionSet.insert(AddrefMI); - MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(MO_FIRST))); + MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(0))); } else { /* Mov */ + unsigned int imm1 = SubSecOffset & 0X000000000000FFFF; Register VRegForMov = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov).addImm(0); + MachineInstr *MovMI = BuildMI(MB, ++II, DL, TII->get(XVM::MOV_ri), VRegForMov) + .addImm(imm1); MachineInstrExceptionSet.insert(MovMI); /* Movk */ - unsigned int imm1 = SubSecOffset & 0X000000000000FFFF; - Register VRegForMovk0 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - MachineInstr *Movk0MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk0) - .addReg(VRegForMov).addImm(imm1).addImm(MOVK_SHIFT_0); - MachineInstrExceptionSet.insert(Movk0MI); - /* Movk */ - unsigned int imm2 = (SubSecOffset & 0X00000000FFFF0000) >> NUM_OF_IMM_BITS_MOV; + unsigned int imm2 = (SubSecOffset & 0X00000000FFFF0000)>>16; Register VRegForMovk1 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *Movk1MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk1) - .addReg(VRegForMovk0).addImm(imm2).addImm(MOVK_SHIFT_16); + .addReg(VRegForMov).addImm(imm2).addImm(1); MachineInstrExceptionSet.insert(Movk1MI); /* Movk */ - unsigned int imm3 = (SubSecOffset & 0X0000FFFF00000000) >> NUM_OF_IMM_BITS_MOVK1; + unsigned int imm3 = (SubSecOffset & 0X0000FFFF00000000)>>32; Register VRegForMovk2 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *Movk2MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk2) - .addReg(VRegForMovk1).addImm(imm3).addImm(MOVK_SHIFT_32); + .addReg(VRegForMovk1).addImm(imm3).addImm(2); MachineInstrExceptionSet.insert(Movk2MI); /* Movk */ - unsigned int imm4 = (SubSecOffset & 0XFFFF000000000000) >> NUM_OF_IMM_BITS_MOVK2; + unsigned int imm4 = (SubSecOffset & 0XFFFF000000000000)>>48; Register VRegForMovk3 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *Movk3MI = BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk3) - .addReg(VRegForMovk2).addImm(imm4).addImm(MOVK_SHIFT_48); + .addReg(VRegForMovk2).addImm(imm4).addImm(3); MachineInstrExceptionSet.insert(Movk3MI); /* Addref only*/ Register VRegForAddref = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); MachineInstr *AddrefMI = BuildMI(MB, II, DL, TII->get(XVM::AddRef_rr), VRegForAddref) - .addReg(MO_def.getReg()).addReg(VRegForMovk3); + .addReg(MO_def.getReg()).addReg(VRegForMovk3); MachineInstrExceptionSet.insert(AddrefMI); - MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(MO_FIRST))); + MORegReplaceMap.insert(std::pair(MO_def.getReg(), &AddrefMI->getOperand(0))); } } } @@ -842,13 +666,13 @@ static void handleOffsetWithInstr(MachineInstr &MI, const char *GlobalName) { static void updatePtrRegRefBasedGlobals(MachineInstr &MI) { switch (MI.getOpcode()) { case XVM::LD_global_imm64: { - assert(MI.getNumOperands() >= NUM_MO_2); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() >= 2); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); if (MO_use.isGlobal()) { const char *GlobalName = MO_use.getGlobal()->getName().data(); - LLVM_DEBUG(dbgs() << "Global:" << GlobalName << " to load.\n"); - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); + LLVM_DEBUG(dbgs() << "Global:" << GlobalName << ' to load.\n'); + MapRefRegInFunc.insert(std::pair(MO_def.getReg(), XVM_SYM_REG_REF)); unsigned int ptrLevel = GetPtrRegisterLevelBasedOnName(GlobalName); if (ptrLevel > 0) { MapPtrRegInFunc.insert(std::pair(MO_def.getReg(), ptrLevel)); @@ -860,16 +684,16 @@ static void updatePtrRegRefBasedGlobals(MachineInstr &MI) { break; } case XVM::LDD: { - assert(MI.getNumOperands() >= NUM_MO_2); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() >= 2); + MachineOperand &MO_def = MI.getOperand(0); + MachineOperand &MO_use = MI.getOperand(1); if (MO_use.isReg()) { std::map::iterator I = MapPtrRegInFunc.find(MO_use.getReg()); if (I != MapPtrRegInFunc.end() && I->second >= 1) { - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); + MapRefRegInFunc.insert(std::pair(MO_def.getReg(), XVM_SYM_REG_REF)); // check the flags to see if the def is a ref - MachineOperand &MO_imm = MI.getOperand(MO_THIRD); + MachineOperand &MO_imm = MI.getOperand(2); if (MO_imm.isImm()) { int64_t imm = MO_imm.getImm(); if (imm == 0) { @@ -884,12 +708,13 @@ static void updatePtrRegRefBasedGlobals(MachineInstr &MI) { break; } case XVM::STD: { - assert(MI.getNumOperands() >= NUM_MO_2); - MachineOperand &MO_use2 = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() >= 2); + MachineOperand &MO_use1 = MI.getOperand(0); + MachineOperand &MO_use2 = MI.getOperand(1); if (MO_use2.isReg()) { std::map::iterator I = MapPtrRegInFunc.find(MO_use2.getReg()); if (I != MapPtrRegInFunc.end() && I->second >= 1) { - SetRegTypeForMO(MO_use2, XVM_SYM_REG_REF); + MapRefRegInFunc.insert(std::pair(MO_use1.getReg(), XVM_SYM_REG_REF)); } } break; @@ -900,20 +725,20 @@ static void updatePtrRegRefBasedGlobals(MachineInstr &MI) { static void checkStoreMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::STB || MI.getOpcode() == XVM::STH || MI.getOpcode() == XVM::STW || MI.getOpcode() == XVM::STD) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_use1 = MI.getOperand(MO_FIRST); - MachineOperand &MO_use2 = MI.getOperand(MO_SECOND); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_use1 = MI.getOperand(0); + MachineOperand &MO_use2 = MI.getOperand(1); assert(MO_use1.isUse()); if (MO_use2.isReg()) { // STW killed %48:xvmgpr, killed %54:xvmgpr, 0 :: (store (s32) into %ir.arrayidx5) assert(MO_use2.isUse()); // always be ref - SetRegTypeForMO(MO_use2, XVM_SYM_REG_REF); + MapRefRegInFunc.insert(std::pair(MO_use2.getReg(), XVM_SYM_REG_REF)); } else if (MO_use2.isFI()) { /* Note: we might need a fix for FI scenario: - * STB killed %6:xvmgpr, %stack.2.atomic-temp, 0 :: (store (s8) into %ir.atomic-temp) - * It will be handled in eliminateFrameIndex. - */ + STB killed %6:xvmgpr, %stack.2.atomic-temp, 0 :: (store (s8) into %ir.atomic-temp) + It will be handled in eliminateFrameIndex. + */ ; } return; @@ -922,16 +747,16 @@ static void checkStoreMIWithRef(MachineInstr &MI) { static bool updateStoreMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { if (MI.getOpcode() == XVM::STD) { - assert(MI.getNumOperands() == NUM_MO_3); - MachineOperand &MO_use1 = MI.getOperand(MO_FIRST); + assert(MI.getNumOperands() == 3); + MachineOperand &MO_use1 = MI.getOperand(0); Register regNo = MO_use1.getReg(); std::map::iterator I = MapRefRegInFunc.find(regNo); if (I != MapRefRegInFunc.end()) { - if (I->second == XVM_SYM_REG_REF && + if (I->second == XVM_SYM_REG_REF && SetNonRefRegInFunc.find(regNo) == SetNonRefRegInFunc.end()) { - MI.setDesc(TII->get(XVM::StoreRef_ri)); - return true; - } + MI.setDesc(TII->get(XVM::StoreRef_ri)); + return true; + } } } return false; @@ -940,11 +765,11 @@ static bool updateStoreMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { static void checkPhiMIWithRef(MachineInstr &MI) { if (MI.getOpcode() == XVM::PHI) { unsigned numOfFrom = MI.getNumOperands() / 2; - assert(numOfFrom * NUM_MO_PER_PHI_BRANCH + 1 == MI.getNumOperands()); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); + assert(numOfFrom * 2 + 1 == MI.getNumOperands()); + MachineOperand &MO_def = MI.getOperand(0); for (unsigned idx = 0; idx < numOfFrom; idx++) { - MachineOperand &MO_use = MI.getOperand(idx*2+1); - setRefFlagFor2Ops(MO_def, MO_use); + MachineOperand &MO_use = MI.getOperand(idx*2+1); + setRefFlagFor2Ops(MO_def, MO_use); } return; } @@ -956,7 +781,7 @@ static bool updatePhiMIWithRef(MachineInstr &MI, const XVMInstrInfo *TII) { } static bool updateRegistersInMI(MachineInstr &MI, const XVMInstrInfo *TII) { - SmallVector OperandsInMI; + SmallVector OperandsInMI; bool replaceOperand = false; if (MachineInstrExceptionSet.find(&MI) == MachineInstrExceptionSet.end()) { for (unsigned int i = 0; i < MI.getNumOperands(); i++) { @@ -970,14 +795,6 @@ static bool updateRegistersInMI(MachineInstr &MI, const XVMInstrInfo *TII) { if (MO.isDef()) isDef = true; MachineOperand NewMO = MachineOperand::CreateReg((I->second)->getReg(), isDef); - // Update the ref information for replaced registers - std::map::iterator IterTmp = MapRefRegInFunc.find(MO.getReg()); - if (IterTmp != MapRefRegInFunc.end()) { - if (IterTmp->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(MO.getReg()) == SetNonRefRegInFunc.end()) { - MapRefRegInFunc[NewMO.getReg()] = XVM_SYM_REG_REF; - } - } OperandsInMI.push_back(NewMO); replaceOperand = true; } @@ -1006,24 +823,24 @@ static bool updateRegistersInMI(MachineInstr &MI, const XVMInstrInfo *TII) { /** * Propogate the non ref registers via COPY and MOV statements * - **/ + * */ static void propogateNonRefInfo(const MachineBasicBlock &MBB) { MachineBasicBlock::const_iterator MBBI = MBB.begin(), E = MBB.end(); while (MBBI != E) { - MachineBasicBlock::const_iterator NMBBI = std::next(MBBI); - const MachineInstr &MI = *MBBI; - MBBI = NMBBI; - // if MO_use is in SetNonRefRegInFunc, then MO_def should be in SetNonRefRegInFunc - if (MI.getOpcode() == XVM::COPY || MI.getOpcode() == XVM::MOV_rr) { - assert(MI.getNumOperands() == NUM_MO_2); - const MachineOperand &MO_def = MI.getOperand(MO_FIRST); - const MachineOperand &MO_use = MI.getOperand(MO_SECOND); - if (MO_def.isReg() && MO_use.isReg()) { - if (SetNonRefRegInFunc.find(MO_use.getReg()) != SetNonRefRegInFunc.end()) { - SetNonRefRegInFunc.insert(MO_def.getReg()); + MachineBasicBlock::const_iterator NMBBI = std::next(MBBI); + const MachineInstr &MI = *MBBI; + MBBI = NMBBI; + // if MO_use is in SetNonRefRegInFunc, then MO_def should be in SetNonRefRegInFunc + if (MI.getOpcode() == XVM::COPY || MI.getOpcode() == XVM::MOV_rr) { + assert(MI.getNumOperands() == 2); + const MachineOperand &MO_def = MI.getOperand(0); + const MachineOperand &MO_use = MI.getOperand(1); + if (MO_def.isReg() && MO_use.isReg()) { + if (SetNonRefRegInFunc.find(MO_use.getReg()) != SetNonRefRegInFunc.end()) { + SetNonRefRegInFunc.insert(MO_def.getReg()); + } } } - } } } @@ -1035,44 +852,44 @@ static void updateNonRefInfoViaCalls(const MachineBasicBlock &MBB, std::set &FuncSet) { MachineBasicBlock::const_iterator MBBI = MBB.begin(), E = MBB.end(); while (MBBI != E) { - MachineBasicBlock::const_iterator NMBBI = std::next(MBBI); - const MachineInstr &MI = *MBBI; - MBBI = NMBBI; - if (MI.getOpcode() == XVM::CALL_IMM) { - assert(MI.getNumOperands() >= NUM_MO_3); - const MachineOperand &MO_0 = MI.getOperand(MO_FIRST); - const MachineOperand &MO_2 = MI.getOperand(MO_THIRD); - if (!MO_0.isReg() && MO_0.isGlobal() && - MO_2.isReg() && MO_2.isImplicit() && MO_2.isDef() && !MO_2.isDead()) { - // Function without ptr as return - if (FuncSet.find(MO_0.getGlobal()->getName().str()) == FuncSet.end()) { - if (MBBI == E) { - return; - } - const MachineInstr &NextMI = *MBBI; - if (NextMI.getOpcode() == XVM::ADJCALLSTACKUP) { - // skip call stack up - MBBI = std::next(MBBI); - if (MBBI == E) { - return; - } - } - // save va reg from the copy with r0 - const MachineInstr &NextNextMI = *MBBI; - if (NextNextMI.getOpcode() == XVM::COPY || - NextNextMI.getOpcode() == XVM::MOV_rr) { - assert(NextNextMI.getNumOperands() == NUM_MO_2); - const MachineOperand &MO_def = NextNextMI.getOperand(MO_FIRST); - const MachineOperand &MO_use = NextNextMI.getOperand(MO_SECOND); - if (MO_def.isReg() && MO_use.isReg()) { - if (MO_use.getReg() == XVM::R0) { - SetNonRefRegInFunc.insert(MO_def.getReg()); + MachineBasicBlock::const_iterator NMBBI = std::next(MBBI); + const MachineInstr &MI = *MBBI; + MBBI = NMBBI; + if (MI.getOpcode() == XVM::CALL_IMM) { + assert(MI.getNumOperands() >= 3); + const MachineOperand &MO_0 = MI.getOperand(0); + const MachineOperand &MO_2 = MI.getOperand(2); + if (!MO_0.isReg() && MO_0.isGlobal() && + MO_2.isReg() && MO_2.isImplicit() && MO_2.isDef() && !MO_2.isDead()) { + // Function without ptr as return + if (FuncSet.find(MO_0.getGlobal()->getName().str()) == FuncSet.end()) { + if (MBBI == E) { + return; + } + const MachineInstr &NextMI = *MBBI; + if (NextMI.getOpcode() == XVM::ADJCALLSTACKUP) { + // skip call stack up + MBBI = std::next(MBBI); + if (MBBI == E) { + return; + } + } + // save va reg from the copy with r0 + const MachineInstr &NextNextMI = *MBBI; + if (NextNextMI.getOpcode() == XVM::COPY || + NextNextMI.getOpcode() == XVM::MOV_rr) { + assert(NextNextMI.getNumOperands() == 2); + const MachineOperand &MO_def = NextNextMI.getOperand(0); + const MachineOperand &MO_use = NextNextMI.getOperand(1); + if (MO_def.isReg() && MO_use.isReg()) { + if (MO_use.getReg() == XVM::R0) { + SetNonRefRegInFunc.insert(MO_def.getReg()); + } + } } } - } } } - } } } @@ -1100,28 +917,10 @@ void XVMUpdateRefInstrForMI::FindNonRefRegInFunc(const MachineFunction &MF) { } } -bool XVMUpdateRefInstrForMI::updateRegistersOfMIInMBB(MachineBasicBlock &MBB) { - int InstNumber = 0; - bool Modified = false; - - MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(), E = MBB.rend(); - // This needs to be done seperately since it may cross BBs - MBBI = MBB.rbegin(), E = MBB.rend(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::reverse_iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - Modified |= updateRegistersInMI(MI, TII); - MBBI = NMBBI; - } - return Modified; -} - bool XVMUpdateRefInstrForMI::runOnMachineFunction(MachineFunction &MF) { TII = MF.getSubtarget().getInstrInfo(); - LLVM_DEBUG(dbgs() << "Check/update refs in fun:" << MF.getFunction().getName().data() << ".\n"); + LLVM_DEBUG(dbgs() << "Check/update refs in fun:" << MF.getFunction().getName().data() << '.\n'); - MapMIToBeFixed.clear(); MapRefRegInFunc.clear(); MapPtrRegInFunc.clear(); MORegReplaceMap.clear(); @@ -1132,428 +931,12 @@ bool XVMUpdateRefInstrForMI::runOnMachineFunction(MachineFunction &MF) { FindNonRefRegInFunc(MF); bool Modified = false; - // scan MBBs in MF - for (auto &MBB : MF) { - Modified |= scanRefInfoInMBB(MBB); - } - // update MBBs in MF for (auto &MBB : MF) { - Modified |= updateRefInfoBasedInMBB(MBB); + Modified |= updateRefInfoInMBB(MBB); } - - for (auto &MBB : MF) { - Modified |= checkAndUpdateOrInMBB(MBB); - Modified |= updateRegistersOfMIInMBB(MBB); - } - - for (auto &MBB : MF) { - doubleCheckRefs(MBB); - } - Modified |= finalFixRefs(); - return Modified; } -bool XVMUpdateRefInstrForMI::finalFixRefs(void) { - bool Modified = false; - std::map::iterator it; - for (it = MapMIToBeFixed.begin(); it != MapMIToBeFixed.end(); it++) { - MachineInstr *MI = it->first; - MachineBasicBlock *MBB = it->second; - - MachineOperand &MO_def = MI->getOperand(MO_FIRST); - if (!MO_def.isReg()) - return Modified; - - Register regNoDef = MO_def.getReg(); - std::map::iterator IForDef = MapRefRegInFunc.find(regNoDef); - switch (MI->getOpcode()) { - default: - break; - case XVM::ADD_ri: { - // make def to be ref - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - - if (IForDef == MapRefRegInFunc.end()) { - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - } else { - MapRefRegInFunc[regNoDef] = XVM_SYM_REG_REF; - } - // change it to be AddRef_ri and - MI->setDesc(TII->get(XVM::AddRef_ri)); - Modified = true; - break; - } - case XVM::ADD_rr: { - // make def to to ref - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - Modified = true; - // Switch the use 1 with use 2 if use 2 is a ref - MachineOperand &MO_use2 = MI->getOperand(2); - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - // by create a new MI - MachineBasicBlock::iterator II = MI->getIterator(); - MachineFunction *MF = MBB->getParent(); - DebugLoc DL = MI->getDebugLoc(); - MachineRegisterInfo &MRI = MF->getRegInfo(); - MachineInstr *ReplaceMI = BuildMI(*MBB, II, DL, TII->get(XVM::AddRef_rr)); - - MachineOperand &NewMO_def = MI->getOperand(0); - MachineOperand &NewMO_use1 = MI->getOperand(1); - MachineOperand &NewMO_use2 = MI->getOperand(2); - - ReplaceMI->addOperand(NewMO_def); - ReplaceMI->addOperand(NewMO_use2); - ReplaceMI->addOperand(NewMO_use1); - MBB->remove_instr(MI); - MRI.verifyUseLists(); - } - } - break; - } - case XVM::AddRef_ri: { - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - Modified = true; - break; - } - case XVM::AddRef_rr: { - MachineOperand &MO_use2 = MI->getOperand(MO_THIRD); - if ((IForDef != MapRefRegInFunc.end() && IForDef->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoDef) != SetNonRefRegInFunc.end()) { - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - } - // Switch the use 1 with use 2 if use 2 is a ref - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - Modified = true; - // by create a new MI - MachineBasicBlock::iterator II = MI->getIterator(); - MachineFunction *MF = MBB->getParent(); - DebugLoc DL = MI->getDebugLoc(); - MachineRegisterInfo &MRI = MF->getRegInfo(); - MachineInstr *ReplaceMI = BuildMI(*MBB, II, DL, TII->get(XVM::AddRef_rr)); - - MachineOperand &MO_def = MI->getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI->getOperand(MO_SECOND); - MachineOperand &MO_use2 = MI->getOperand(MO_THIRD); - - ReplaceMI->addOperand(MO_def); - ReplaceMI->addOperand(MO_use2); - ReplaceMI->addOperand(MO_use1); - MBB->remove_instr(MI); - MRI.verifyUseLists(); - } - } - break; - } - } - } - return Modified; -} - -void XVMUpdateRefInstrForMI::doubleCheckRefs(MachineBasicBlock &MBB) { - MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); - int InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - - if (MI.getNumOperands() < 2) { - MBBI = NMBBI; - continue; - } - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - MachineOperand &MO_use1 = MI.getOperand(MO_SECOND); - if (!MO_def.isReg()) { - MBBI = NMBBI; - continue; - } - Register regNoDef = MO_def.getReg(); - std::map::iterator IForDef = MapRefRegInFunc.find(regNoDef); - - const MachineFunction *F = MI.getParent()->getParent(); - switch (MI.getOpcode()) { - case XVM::ADD_ri: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isImm()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of ADD_ri is not an imm", NULL); - exit(1); - } - if (IForDef != MapRefRegInFunc.end()) { - if (IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(ADD_ri): def is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if (IForUse1 != MapRefRegInFunc.end()) { - if (IForUse1->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse1) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(ADD_ri): use 1 is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - break; - } - case XVM::ADD_rr: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isReg()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of ADD_rr is not a reg", NULL); - exit(1); - } - if (IForDef != MapRefRegInFunc.end()) { - if (IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(ADD_rr): def is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - Register regNoUse1 = MO_use1.getReg(); - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - if (IForUse1 != MapRefRegInFunc.end()) { - if (IForUse1->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse1) == SetNonRefRegInFunc.end()) { - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: both use 1 and use2 of ADD_rr are ref", NULL); - exit(1); - } - } - } - } else { - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(ADD_ri): use 1 is not ref, use 2 is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - } - break; - } - case XVM::SUB_ri: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isImm()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of SUB_ri is not imm", NULL); - exit(1); - } - if (IForDef != MapRefRegInFunc.end()) { - if (IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SUB_ri): def is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if (IForUse1 != MapRefRegInFunc.end()) { - if (IForUse1->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse1) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SUB_ri): use 1 is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - break; - } - case XVM::SUB_rr: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isReg()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of SUB_rr is not a reg", NULL); - exit(1); - } - if (IForDef != MapRefRegInFunc.end()) { - if (IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SUB_rr): def is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if (IForUse1 != MapRefRegInFunc.end()) { - if (IForUse1->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse1) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SUB_rr): use 1 is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SUB_rr): use 2 is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - break; - } - case XVM::SubRef_ri: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isImm()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of SubRef_ri is not an imm", NULL); - exit(1); - } - if ((IForDef != MapRefRegInFunc.end() && IForDef->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoDef) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SubRef_ri): def is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if ((IForUse1 != MapRefRegInFunc.end() && IForUse1->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoUse1) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SubRef_ri): use 1 is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - break; - } - case XVM::AddRef_ri: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isImm()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(AddRef_ri): use 2 is not imm.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - exit(1); - } - if ((IForDef != MapRefRegInFunc.end() && IForDef->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoDef) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(AddRef_ri): def is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if ((IForUse1 != MapRefRegInFunc.end() && IForUse1->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoUse1) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(AddRef_ri): use 1 is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - break; - } - case XVM::SubRef_rr: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isReg()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of SubRef_rr is not a reg", NULL); - exit(1); - } - if ((IForDef != MapRefRegInFunc.end() && IForDef->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoDef) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SubRef_rr): def is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if ((IForUse1 != MapRefRegInFunc.end() && IForUse1->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoUse1) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SubRef_rr): use 1 is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(SubRef_rr): use 2 is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - if ((IForUse1 != MapRefRegInFunc.end() && IForUse1->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse1) == SetNonRefRegInFunc.end()) && - (IForUse2 != MapRefRegInFunc.end() && IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end())) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: both use 1 and use 2 of SubRef_rr are ref", NULL); - exit(1); - } - break; - } - case XVM::AddRef_rr: { - MachineOperand &MO_use2 = MI.getOperand(MO_THIRD); - if (!MO_use2.isReg()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 2 of AddRef_rr is not a reg", NULL); - exit(1); - } - if ((IForDef != MapRefRegInFunc.end() && IForDef->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoDef) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(AddRef_rr): def is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if ((IForUse1 != MapRefRegInFunc.end() && IForUse1->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoUse1) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(AddRef_rr): use 1 is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - Register regNoUse2 = MO_use2.getReg(); - std::map::iterator IForUse2 = MapRefRegInFunc.find(regNoUse2); - if (IForUse2 != MapRefRegInFunc.end()) { - if (IForUse2->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse2) == SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "\nTest To-be-fixed(AddRef_rr): use 2 is ref. Regno: " << regNoUse2 << " Reg1: " << regNoUse1 << "\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - break; - } - case XVM::MOV_rr: { - if (MO_use1.isFI()) { - // def has to be ref - if ((IForDef != MapRefRegInFunc.end() && IForDef->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoDef) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(MOV_rr): def is not ref for the case of use=sp.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } else { - // if def is ref, then use1 is ref - if (IForDef != MapRefRegInFunc.end()) { - if (IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) { - // check to see if use1 is ref - Register regNoUse1 = MO_use1.getReg(); - std::map::iterator IForUse1 = MapRefRegInFunc.find(regNoUse1); - if ((IForUse1 != MapRefRegInFunc.end() && IForUse1->second != XVM_SYM_REG_REF) || - SetNonRefRegInFunc.find(regNoUse1) != SetNonRefRegInFunc.end()) { - LLVM_DEBUG(dbgs() << "To-be-fixed(MOV_rr): def is ref while use is not ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - } - } - break; - } - case XVM::MOV_ri: { - if (!MO_use1.isImm()) { - ExportFailMsg(F->getFunction(), MI.getDebugLoc(), "Error: use 1 of MOV_ri is not an imm", NULL); - exit(1); - } - if (IForDef != MapRefRegInFunc.end()) { - if (IForDef->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoDef) == SetNonRefRegInFunc.end()) { - MI.print(dbgs()); - LLVM_DEBUG(dbgs() << "To-be-fixed(MOV_ri): def is ref.\n"); - MapMIToBeFixed.insert(std::pair(&MI, &MBB)); - } - } - break; - } - default: - break; - } - MBBI = NMBBI; - } -} - void XVMUpdateRefInstrForMI::updatePtrRefInMBB(MachineBasicBlock &MBB) { MachineBasicBlock::iterator MBBI = MBB.begin(); int InstNumber = std::distance(MBB.begin(), MBB.end()); @@ -1565,199 +948,28 @@ void XVMUpdateRefInstrForMI::updatePtrRefInMBB(MachineBasicBlock &MBB) { } } -/** - * We need to consider the static recurisive case. Here is an example - * %46:xvmgpr = ADD_ri %47:xvmgpr, 24 - * - * %47:xvmgpr = PHI %44:xvmgpr, %bb.75, %46:xvmgpr, %bb.45 - * - * In the above code, %47 depends on %44 and %46 while %46 depends on %47 - * Once we detect the %44 is ref, then we should conclude that both %46 and %47 are ref - * - * Also, we reverse scan the instructions: Phi instructions need double check. Here is an example: - * %85:xvmgpr = LD_global_imm64 @crc32_tab - * - * %0:xvmgpr = PHI %85:xvmgpr, %bb.0, %3:xvmgpr, %bb.60 <-- checking of %85 is done after that of PHI - **/ -void XVMUpdateRefInstrForMI::doubleCheckPhiMIWithRef(MachineBasicBlock &MBB) { - MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); - int InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - if (MI.getOpcode() != XVM::PHI) { - MBBI = NMBBI; - continue; - } - - unsigned numOfFrom = MI.getNumOperands() / 2; - assert(numOfFrom * NUM_MO_PER_PHI_BRANCH + 1 == MI.getNumOperands()); - MachineOperand &MO_def = MI.getOperand(MO_FIRST); - Register regNoDef = MO_def.getReg(); - - std::map::iterator IDef = MapRefRegInFunc.find(regNoDef); - if (IDef != MapRefRegInFunc.end() && IDef->second == XVM_SYM_REG_REF) { - // def is ref: all uses should be ref - for (unsigned idx = 0; idx < numOfFrom; idx++) { - MachineOperand &MO_use = MI.getOperand(idx*2+1); - Register regNoUse = MO_use.getReg(); - std::map::iterator IUse = MapRefRegInFunc.find(regNoUse); - if (IUse == MapRefRegInFunc.end() || IUse->second != XVM_SYM_REG_REF) { - SetRegTypeForMO(MO_use, XVM_SYM_REG_REF); - SetNonRefRegInFunc.erase(MO_use.getReg()); - } - } - } else { - // if any (def and uses) is ref, then all should be ref - bool anyIsRef = false; - for (unsigned idx = 0; idx < numOfFrom; idx++) { - MachineOperand &MO_use = MI.getOperand(idx*2+1); - Register regNoUse = MO_use.getReg(); - std::map::iterator IUse = MapRefRegInFunc.find(regNoUse); - if (IUse != MapRefRegInFunc.end() && IUse->second == XVM_SYM_REG_REF && - SetNonRefRegInFunc.find(regNoUse) == SetNonRefRegInFunc.end()) { - anyIsRef = true; - break; - } - } - if (anyIsRef) { - // make all reg to be ref - SetRegTypeForMO(MO_def, XVM_SYM_REG_REF); - for (unsigned idx = 0; idx < numOfFrom; idx++) { - MachineOperand &MO_use = MI.getOperand(idx*2+1); - SetRegTypeForMO(MO_use, XVM_SYM_REG_REF); - } - } - } - MBBI = NMBBI; - } -} - -static int ShiftAndGet16Bits(uint64_t num, int n) { - return (num >> n) & 0xFFFF; -} - -static void replaceImmWithMovk(MachineInstr &MI) { - MachineBasicBlock &MB = *MI.getParent(); - MachineFunction *MF = MB.getParent(); - const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); - MachineRegisterInfo &MRI = MF->getRegInfo(); - DebugLoc DL = MI.getDebugLoc(); - int64_t imm32 = MI.getOperand(MO_THIRD).getImm(); - MachineBasicBlock::iterator II = MI.getIterator(); - - Register ScratchReg; - ScratchReg = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - uint64_t MostSignificantBits = ShiftAndGet16Bits(imm32, MOST_SIGNIFICANT); - uint64_t UpperMiddleBits = ShiftAndGet16Bits(imm32, UPPER_MIDDLE); - uint64_t LowerMiddleBits = ShiftAndGet16Bits(imm32, LOWER_MIDDLE); - uint64_t LeastSignificantBits = ShiftAndGet16Bits(imm32, LEAST_SIGNIFICANT); - - Register VRegForMov = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - BuildMI(MB, II, DL, TII->get(XVM::MOV_ri), VRegForMov).addImm(0); - Register PrevReg = VRegForMov; - if (LeastSignificantBits) { - Register VRegForMovk1 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk1) - .addReg(PrevReg).addImm(LeastSignificantBits).addImm(MOVK_SHIFT_0); - PrevReg = VRegForMovk1; - } - if (LowerMiddleBits) { - Register VRegForMovk2 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk2) - .addReg(PrevReg).addImm(LowerMiddleBits).addImm(MOVK_SHIFT_16); - PrevReg = VRegForMovk2; - } - if (UpperMiddleBits) { - Register VRegForMovk3 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk3) - .addReg(PrevReg).addImm(UpperMiddleBits).addImm(MOVK_SHIFT_32); - PrevReg = VRegForMovk3; - } - if (MostSignificantBits) { - Register VRegForMovk4 = MRI.createVirtualRegister(&XVM::XVMGPRRegClass); - BuildMI(MB, II, DL, TII->get(XVM::MOVK_ri), VRegForMovk4) - .addReg(PrevReg).addImm(MostSignificantBits).addImm(MOVK_SHIFT_48); - PrevReg = VRegForMovk4; - } - - BuildMI(MB, II, DL, TII->get(XVM::AddRef_rr)).addReg(ScratchReg, RegState::Define) - .addReg(MI.getOperand(MO_SECOND).getReg()) - .addReg(PrevReg); - MI.getOperand(MO_SECOND).setReg(ScratchReg); - MI.getOperand(MO_SECOND).setIsKill(); - MI.getOperand(MO_THIRD).setImm(0); -} - -bool XVMUpdateRefInstrForMI::checkAndUpdateOrInMBB(MachineBasicBlock &MBB) { - int InstNumber = 0; - bool Modified = false; - /* Note: the two passes may be merged for efficiency */ - MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(), E = MBB.rend(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::reverse_iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - checkOrXorAndMIWithRef(MI); - MBBI = NMBBI; - } - /* update the instructions */ - MBBI = MBB.rbegin(), E = MBB.rend(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::reverse_iterator NMBBI = std::next(MBBI); - MachineInstr &MI = *MBBI; - Modified |= updateOrXorAndMIWithRef(MBB, MI, TII); - MBBI = NMBBI; - } - return Modified; -} - -bool XVMUpdateRefInstrForMI::scanRefInfoInMBB(MachineBasicBlock &MBB) { +bool XVMUpdateRefInstrForMI::updateRefInfoInMBB(MachineBasicBlock &MBB) { int InstNumber = 0; bool Modified = false; updatePtrRefInMBB(MBB); /* Note: the two passes may be merged for efficiency */ - // reverse order - MachineBasicBlock::reverse_iterator R_MBBI = MBB.rbegin(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::reverse_iterator NMBBI = std::next(R_MBBI); - MachineInstr &MI = *R_MBBI; - checkSimpleMIWithRef(MI); - checkMovMIWithRef(MI); - checkLoadMIWithRef(MI); - checkStoreMIWithRef(MI); - checkAddSubMIWithRef(MI); - checkPhiMIWithRef(MI); - R_MBBI = NMBBI; - } - // normal order - MachineBasicBlock::iterator MBBI = MBB.begin(); + MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(), E = MBB.rend(); InstNumber = std::distance(MBB.begin(), MBB.end()); for (int i = 0; i < InstNumber; i++) { - MachineBasicBlock::iterator NMBBI = std::next(MBBI); + MachineBasicBlock::reverse_iterator NMBBI = std::next(MBBI); MachineInstr &MI = *MBBI; checkSimpleMIWithRef(MI); checkMovMIWithRef(MI); checkLoadMIWithRef(MI); checkStoreMIWithRef(MI); checkAddSubMIWithRef(MI); + checkOrXorAndMIWithRef(MI); checkPhiMIWithRef(MI); MBBI = NMBBI; } - return Modified; -} - -bool XVMUpdateRefInstrForMI::updateRefInfoBasedInMBB(MachineBasicBlock &MBB) { - int InstNumber = 0; - bool Modified = false; - updatePtrRefInMBB(MBB); - /* Note: the two passes may be merged for efficiency */ - doubleCheckPhiMIWithRef(MBB); /* update the instructions */ - MachineBasicBlock::reverse_iterator MBBI = MBB.rbegin(), E = MBB.rend(); + MBBI = MBB.rbegin(), E = MBB.rend(); InstNumber = std::distance(MBB.begin(), MBB.end()); for (int i = 0; i < InstNumber; i++) { MachineBasicBlock::reverse_iterator NMBBI = std::next(MBBI); @@ -1767,45 +979,11 @@ bool XVMUpdateRefInstrForMI::updateRefInfoBasedInMBB(MachineBasicBlock &MBB) { Modified |= updateLoadMIWithRef(MI, TII); Modified |= updateStoreMIWithRef(MI, TII); Modified |= updateAddSubMIWithRef(MI, TII); - // Modified |= updateOrXorAndMIWithRef(MI, TII); + Modified |= updateOrXorAndMIWithRef(MI, TII); Modified |= updatePhiMIWithRef(MI, TII); + Modified |= updateRegistersInMI(MI, TII); MBBI = NMBBI; } - - MBBI = MBB.rbegin(), E = MBB.rend(); - InstNumber = std::distance(MBB.begin(), MBB.end()); - for (MachineBasicBlock::iterator MBBI = MBB.begin(), MBBE = MBB.end(); MBBI != MBBE; MBBI++) { - MachineInstr &MI = *MBBI; - switch (MI.getOpcode()) { - case XVM::STW: - case XVM::STH: - case XVM::STB: - case XVM::STD: - case XVM::LDW_z: - case XVM::LDH_z: - case XVM::LDB_z: - case XVM::LDW: - case XVM::LDH: - case XVM::LDB: - case XVM::LDD: - if (MI.getOperand(MO_THIRD).isImm()) { - int64_t imm32 = MI.getOperand(MO_THIRD).getImm(); - if (imm32 > MAX_IMM || imm32 < -(MAX_IMM + 1)) { - if (MI.getOperand(MO_SECOND).isFI()) { - MachineFunction *MF = MBB.getParent(); - const Function &F = MF->getFunction(); - ExportFailMsg(F.getFunction(), MI.getDebugLoc(), "Error: Max stack size (1024) reached", (void*)&imm32); - exit(1); - } - Modified = true; - replaceImmWithMovk(MI); - } - } - default: - continue; - } - } - return Modified; } diff --git a/llvm/lib/Target/XVM/XVM_def.h b/llvm/lib/Target/XVM/XVM_def.h index 452d690b71c9..ac0910a01792 100644 --- a/llvm/lib/Target/XVM/XVM_def.h +++ b/llvm/lib/Target/XVM/XVM_def.h @@ -36,27 +36,9 @@ meaning: | reserved X W R #define XVM_SECTION_DATA_TYPE_STRUCT 0b00100000 #define XVM_SECTION_DATA_TYPE_BSS 0b01000000 -#define MOVK_SHIFT_0 0 -#define MOVK_SHIFT_16 1 -#define MOVK_SHIFT_32 2 -#define MOVK_SHIFT_48 3 - -#define MOST_SIGNIFICANT 48 -#define UPPER_MIDDLE 32 -#define LOWER_MIDDLE 16 -#define LEAST_SIGNIFICANT 0 - -#define MO_FIRST 0 -#define MO_SECOND 1 -#define MO_THIRD 2 -#define MO_FOURTH 3 -#define MO_FIFTH 4 -#define MO_SIXTH 5 - typedef struct XVMGVPatchInfo { std::string SymName; int AddEnd; - unsigned int LocInByte; } XVMGVPathInfo; typedef struct XVMSectionInfo { -- Gitee