From 38c9ecda9bf92a3bcea30096aeb170978526b925 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 13 Dec 2013 18:57:20 +0000 Subject: [PATCH] Revert "Liveness Analysis Pass" This reverts commit r197254. This was an accidental merge of Juergen's patch. It will be checked in shortly, but wasn't meant to go in quite yet. Conflicts: include/llvm/CodeGen/StackMaps.h lib/CodeGen/StackMaps.cpp test/CodeGen/X86/stackmap-liveness.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197260 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineFrameInfo.h | 11 -- include/llvm/CodeGen/MachineFunction.h | 9 -- include/llvm/CodeGen/MachineOperand.h | 17 +-- include/llvm/CodeGen/Passes.h | 5 - .../llvm/CodeGen/StackMapLivenessAnalysis.h | 67 --------- include/llvm/CodeGen/StackMaps.h | 30 +--- include/llvm/InitializePasses.h | 1 - lib/CodeGen/CMakeLists.txt | 1 - lib/CodeGen/CodeGen.cpp | 1 - lib/CodeGen/MachineInstr.cpp | 7 +- lib/CodeGen/Passes.cpp | 5 - .../SelectionDAG/SelectionDAGBuilder.cpp | 6 - lib/CodeGen/StackMapLivenessAnalysis.cpp | 128 ------------------ lib/CodeGen/StackMaps.cpp | 119 ++-------------- test/CodeGen/X86/stackmap-liveness.ll | 85 ------------ test/CodeGen/X86/stackmap.ll | 68 +++++----- 16 files changed, 52 insertions(+), 508 deletions(-) delete mode 100644 include/llvm/CodeGen/StackMapLivenessAnalysis.h delete mode 100644 lib/CodeGen/StackMapLivenessAnalysis.cpp delete mode 100644 test/CodeGen/X86/stackmap-liveness.ll diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 163a9154c6f..747938f3f9f 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -145,10 +145,6 @@ class MachineFrameInfo { /// to builtin \@llvm.returnaddress. bool ReturnAddressTaken; - /// HasStackmap - This boolean keeps track of whether there is a call - /// to builtin \@llvm.experimental.stackmap or \@llvm.experimental.patchpoint. - bool HasStackMap; - /// StackSize - The prolog/epilog code inserter calculates the final stack /// offsets for all of the fixed size objects, updating the Objects list /// above. It then updates StackSize to contain the number of bytes that need @@ -239,7 +235,6 @@ public: HasVarSizedObjects = false; FrameAddressTaken = false; ReturnAddressTaken = false; - HasStackMap = false; AdjustsStack = false; HasCalls = false; StackProtectorIdx = -1; @@ -285,12 +280,6 @@ public: bool isReturnAddressTaken() const { return ReturnAddressTaken; } void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; } - /// hasStackMap - This method may be called any time after instruction - /// selection is complete to determine if there is a call to builtin - /// \@llvm.experimental.stackmap or \@llvm.experimental.patchpoint. - bool hasStackMap() const { return HasStackMap; } - void setHasStackMap(bool s = true) { HasStackMap = s; } - /// getObjectIndexBegin - Return the minimum frame object index. /// int getObjectIndexBegin() const { return -NumFixedObjects; } diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index 09cc1e5dfb8..43b370cccff 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -426,15 +426,6 @@ public: OperandRecycler.deallocate(Cap, Array); } - /// \brief Allocate and initialize a register mask with @p NumRegister bits. - uint32_t *allocateRegisterMask(unsigned NumRegister) { - unsigned Size = (NumRegister + 31) / 32; - uint32_t *Mask = Allocator.Allocate(Size); - for (unsigned i = 0; i != Size; ++i) - Mask[i] = 0; - return Mask; - } - /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand /// pointers. This array is owned by the MachineFunction. MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num); diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index c2a0f656663..40f3580bfdb 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -56,7 +56,6 @@ public: MO_GlobalAddress, ///< Address of a global value MO_BlockAddress, ///< Address of a basic block MO_RegisterMask, ///< Mask of preserved registers. - MO_RegisterLiveOut, ///< Mask of live-out registers. MO_Metadata, ///< Metadata reference (for debug info) MO_MCSymbol ///< MCSymbol reference (for debug/eh info) }; @@ -154,7 +153,7 @@ private: const ConstantFP *CFP; // For MO_FPImmediate. const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit. int64_t ImmVal; // For MO_Immediate. - const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut. + const uint32_t *RegMask; // For MO_RegisterMask. const MDNode *MD; // For MO_Metadata. MCSymbol *Sym; // For MO_MCSymbol @@ -247,8 +246,6 @@ public: bool isBlockAddress() const { return OpKind == MO_BlockAddress; } /// isRegMask - Tests if this is a MO_RegisterMask operand. bool isRegMask() const { return OpKind == MO_RegisterMask; } - /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand. - bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; } /// isMetadata - Tests if this is a MO_Metadata operand. bool isMetadata() const { return OpKind == MO_Metadata; } bool isMCSymbol() const { return OpKind == MO_MCSymbol; } @@ -479,12 +476,6 @@ public: return Contents.RegMask; } - /// getRegLiveOut - Returns a bit mask of live-out registers. - const uint32_t *getRegLiveOut() const { - assert(isRegLiveOut() && "Wrong MachineOperand accessor"); - return Contents.RegMask; - } - const MDNode *getMetadata() const { assert(isMetadata() && "Wrong MachineOperand accessor"); return Contents.MD; @@ -668,12 +659,6 @@ public: Op.Contents.RegMask = Mask; return Op; } - static MachineOperand CreateRegLiveOut(const uint32_t *Mask) { - assert(Mask && "Missing live-out register mask"); - MachineOperand Op(MachineOperand::MO_RegisterLiveOut); - Op.Contents.RegMask = Mask; - return Op; - } static MachineOperand CreateMetadata(const MDNode *Meta) { MachineOperand Op(MachineOperand::MO_Metadata); Op.Contents.MD = Meta; diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 3fbc081ea3b..ae4a2fa0bf8 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -568,11 +568,6 @@ namespace llvm { /// bundles (created earlier, e.g. during pre-RA scheduling). extern char &FinalizeMachineBundlesID; - /// StackMapLiveness - This pass analyses the register live-out set of - /// stackmap/patchpoint intrinsics and attaches the calculated information to - /// the intrinsic for later emission to the StackMap. - extern char &StackMapLivenessID; - } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h deleted file mode 100644 index 4631f0fa79a..00000000000 --- a/include/llvm/CodeGen/StackMapLivenessAnalysis.h +++ /dev/null @@ -1,67 +0,0 @@ -//===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass calculates the liveness for each basic block in a function and -// attaches the register live-out information to a stackmap or patchpoint -// intrinsic if present. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H -#define LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H - -#include "llvm/CodeGen/LivePhysRegs.h" -#include "llvm/CodeGen/MachineFunctionPass.h" - - -namespace llvm { - -/// \brief This pass calculates the liveness information for each basic block in -/// a function and attaches the register live-out information to a stackmap or -/// patchpoint intrinsic if present. -/// -/// This is an optional pass that has to be explicitely enabled via the -/// -enable-stackmap-liveness flag. The pass skips functions that don't have any -/// stackmap or patchpoint intrinsics. The information provided by this pass is -/// optional and not required by the aformentioned intrinsics to function. -class StackMapLiveness : public MachineFunctionPass { - MachineFunction *MF; - const TargetRegisterInfo *TRI; - LivePhysRegs LiveRegs; -public: - static char ID; - - /// \brief Default construct and initialize the pass. - StackMapLiveness(); - - /// \brief Tell the pass manager which passes we depend on and what - /// information we preserve. - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - - /// \brief Calculate the liveness information for the given machine function. - virtual bool runOnMachineFunction(MachineFunction &MF); - -private: - /// \brief Performs the actual liveness calculation for the function. - bool calculateLiveness(); - - /// \brief Add the current register live set to the instruction. - void addLiveOutSetToMI(MachineInstr &MI); - - /// \brief Create a register mask and initialize it with the registers from - /// the register live set. - uint32_t *createRegisterMask() const; - - /// \brief Print the current register live set for debugging. - void printLiveOutSet(raw_ostream &OS) const; -}; - -} // end llvm namespace - -#endif // end LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h index 1bf5b5e80df..c61ba59eebc 100644 --- a/include/llvm/CodeGen/StackMaps.h +++ b/include/llvm/CodeGen/StackMaps.h @@ -93,20 +93,6 @@ public: : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {} }; - struct LiveOutReg { - unsigned short Reg; - unsigned short RegNo; - unsigned short Size; - - LiveOutReg() : Reg(0), RegNo(0), Size(0) {} - LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size) - : Reg(Reg), RegNo(RegNo), Size(Size) {} - - // Only sort by the dwarf register number. - bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; } - static bool isInvalid(const LiveOutReg &LO) { return LO.Reg == 0; } - }; - // OpTypes are used to encode information about the following logical // operand (which may consist of several MachineOperands) for the // OpParser. @@ -129,18 +115,15 @@ public: private: typedef SmallVector LocationVec; - typedef SmallVector LiveOutVec; struct CallsiteInfo { const MCExpr *CSOffsetExpr; uint64_t ID; LocationVec Locations; - LiveOutVec LiveOuts; CallsiteInfo() : CSOffsetExpr(0), ID(0) {} CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID, - LocationVec &Locations, LiveOutVec &LiveOuts) - : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations), - LiveOuts(LiveOuts) {} + LocationVec Locations) + : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations) {} }; typedef std::vector CallsiteInfoList; @@ -171,15 +154,8 @@ private: std::pair parseOperand(MachineInstr::const_mop_iterator MOI, - MachineInstr::const_mop_iterator MOE) const; + MachineInstr::const_mop_iterator MOE); - /// \brief Create a live-out register record for the given register @p Reg. - LiveOutReg createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI, - const TargetRegisterInfo *TRI) const; - - /// \brief Parse the register live-out mask and return a vector of live-out - /// registers that need to be recorded in the stackmap. - LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const; /// This should be called by the MC lowering code _immediately_ before /// lowering the MI to an MCInst. It records where the operands for the diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 7be62ca47c7..029ae30859e 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -266,7 +266,6 @@ void initializeLoopVectorizePass(PassRegistry&); void initializeSLPVectorizerPass(PassRegistry&); void initializeBBVectorizePass(PassRegistry&); void initializeMachineFunctionPrinterPassPass(PassRegistry&); -void initializeStackMapLivenessPass(PassRegistry&); } #endif diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 123d86f9504..0beca0ceedc 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -97,7 +97,6 @@ add_llvm_library(LLVMCodeGen StackColoring.cpp StackProtector.cpp StackSlotColoring.cpp - StackMapLivenessAnalysis.cpp StackMaps.cpp TailDuplication.cpp TargetFrameLoweringImpl.cpp diff --git a/lib/CodeGen/CodeGen.cpp b/lib/CodeGen/CodeGen.cpp index 30b40a12da1..7430c53b8da 100644 --- a/lib/CodeGen/CodeGen.cpp +++ b/lib/CodeGen/CodeGen.cpp @@ -69,7 +69,6 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeVirtRegRewriterPass(Registry); initializeLowerIntrinsicsPass(Registry); initializeMachineFunctionPrinterPassPass(Registry); - initializeStackMapLivenessPass(Registry); } void LLVMInitializeCodeGen(LLVMPassRegistryRef R) { diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 34eeea23334..295b450a0f2 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -199,8 +199,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { case MachineOperand::MO_BlockAddress: return getBlockAddress() == Other.getBlockAddress() && getOffset() == Other.getOffset(); - case MachineOperand::MO_RegisterMask: - case MachineOperand::MO_RegisterLiveOut: + case MO_RegisterMask: return getRegMask() == Other.getRegMask(); case MachineOperand::MO_MCSymbol: return getMCSymbol() == Other.getMCSymbol(); @@ -242,7 +241,6 @@ hash_code llvm::hash_value(const MachineOperand &MO) { return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), MO.getOffset()); case MachineOperand::MO_RegisterMask: - case MachineOperand::MO_RegisterLiveOut: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); case MachineOperand::MO_Metadata: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); @@ -370,9 +368,6 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { case MachineOperand::MO_RegisterMask: OS << ""; break; - case MachineOperand::MO_RegisterLiveOut: - OS << ""; - break; case MachineOperand::MO_Metadata: OS << '<'; WriteAsOperand(OS, getMetadata(), /*PrintType=*/false); diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index e9f780cf130..db7021372bc 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -69,8 +69,6 @@ static cl::opt DisableCGP("disable-cgp", cl::Hidden, cl::desc("Disable Codegen Prepare")); static cl::opt DisableCopyProp("disable-copyprop", cl::Hidden, cl::desc("Disable Copy Propagation pass")); -static cl::opt EnableStackMapLiveness("enable-stackmap-liveness", - cl::Hidden, cl::desc("Enable StackMap Liveness Analysis Pass")); static cl::opt PrintLSR("print-lsr-output", cl::Hidden, cl::desc("Print LLVM IR produced by the loop-reduce pass")); static cl::opt PrintISelInput("print-isel-input", cl::Hidden, @@ -538,9 +536,6 @@ void TargetPassConfig::addMachinePasses() { if (addPreEmitPass()) printAndVerify("After PreEmit passes"); - - if (EnableStackMapLiveness) - addPass(&StackMapLivenessID); } /// Add passes that optimize machine instructions in SSA form. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index f539a1636f1..1eb590b55f8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6886,9 +6886,6 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) { DAG.ReplaceAllUsesWith(Call, MN); DAG.DeleteNode(Call); - - // Inform the Frame Information that we have a stackmap in this function. - FuncInfo.MF->getFrameInfo()->setHasStackMap(); } /// \brief Lower llvm.experimental.patchpoint directly to its target opcode. @@ -7028,9 +7025,6 @@ void SelectionDAGBuilder::visitPatchpoint(const CallInst &CI) { } else DAG.ReplaceAllUsesWith(Call, MN); DAG.DeleteNode(Call); - - // Inform the Frame Information that we have a stackmap in this function. - FuncInfo.MF->getFrameInfo()->setHasStackMap(); } /// TargetLowering::LowerCallTo - This is the default LowerCallTo diff --git a/lib/CodeGen/StackMapLivenessAnalysis.cpp b/lib/CodeGen/StackMapLivenessAnalysis.cpp deleted file mode 100644 index 788b83416ba..00000000000 --- a/lib/CodeGen/StackMapLivenessAnalysis.cpp +++ /dev/null @@ -1,128 +0,0 @@ -//===-- StackMapLivenessAnalysis.cpp - StackMap live Out Analysis ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the StackMap Liveness analysis pass. The pass calculates -// the liveness for each basic block in a function and attaches the register -// live-out information to a stackmap or patchpoint intrinsic if present. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "stackmaps" -#include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionAnalysis.h" -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/StackMapLivenessAnalysis.h" -#include "llvm/Support/Debug.h" - -using namespace llvm; - - -STATISTIC(NumStackMapFuncVisited, "Number of functions visited"); -STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped"); -STATISTIC(NumBBsVisited, "Number of basic blocks visited"); -STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap"); -STATISTIC(NumStackMaps, "Number of StackMaps visited"); - -char StackMapLiveness::ID = 0; -char &llvm::StackMapLivenessID = StackMapLiveness::ID; -INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness", - "StackMap Liveness Analysis", false, false) - -/// Default construct and initialize the pass. -StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) { - initializeStackMapLivenessPass(*PassRegistry::getPassRegistry()); -} - -/// Tell the pass manager which passes we depend on and what information we -/// preserve. -void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const { - // We preserve all information. - AU.setPreservesAll(); - AU.setPreservesCFG(); - // Default dependencie for all MachineFunction passes. - AU.addRequired(); -} - -/// Calculate the liveness information for the given machine function. -bool StackMapLiveness::runOnMachineFunction(MachineFunction &_MF) { - DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " - << _MF.getName() << " **********\n"); - MF = &_MF; - TRI = MF->getTarget().getRegisterInfo(); - ++NumStackMapFuncVisited; - - // Skip this function if there are no stackmaps. - if (!MF->getFrameInfo()->hasStackMap()) { - ++NumStackMapFuncSkipped; - return false; - } - return calculateLiveness(); -} - -/// Performs the actual liveness calculation for the function. -bool StackMapLiveness::calculateLiveness() { - bool HasChanged = false; - // For all basic blocks in the function. - for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); - MBBI != MBBE; ++MBBI) { - DEBUG(dbgs() << "****** BB " << MBBI->getName() << " ******\n"); - LiveRegs.init(TRI); - LiveRegs.addLiveOuts(MBBI); - bool HasStackMap = false; - // Reverse iterate over all instructions and add the current live register - // set to an instruction if we encounter a stackmap or patchpoint - // instruction. - for (MachineBasicBlock::reverse_iterator I = MBBI->rbegin(), - E = MBBI->rend(); I != E; ++I) { - if (I->getOpcode() == TargetOpcode::STACKMAP || - I->getOpcode() == TargetOpcode::PATCHPOINT) { - addLiveOutSetToMI(*I); - HasChanged = true; - HasStackMap = true; - ++NumStackMaps; - } - LiveRegs.stepBackward(*I); - } - ++NumBBsVisited; - if (!HasStackMap) - ++NumBBsHaveNoStackmap; - } - return HasChanged; -} - -/// Add the current register live set to the instruction. -void StackMapLiveness::addLiveOutSetToMI(MachineInstr &MI) { - uint32_t *Mask = createRegisterMask(); - MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask); - MI.addOperand(*MF, MO); - DEBUG(dbgs() << " " << MI); - DEBUG(printLiveOutSet(dbgs())); -} - -/// Create a register mask and initialize it with the registers from the -/// register live set. -uint32_t *StackMapLiveness::createRegisterMask() const { - // The mask is owned and cleaned up by the Machine Function. - uint32_t *Mask = MF->allocateRegisterMask(TRI->getNumRegs()); - for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end(); - RI != RE; ++RI) - Mask[*RI / 32] |= 1U << (*RI % 32); - return Mask; -} - -/// Print the current register live set for debugging. -void StackMapLiveness::printLiveOutSet(raw_ostream &OS) const { - OS << " Register live-out:"; - for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end(); - RI != RE; ++RI) - OS << " " << TRI->getName(*RI); - OS << "\n"; -} diff --git a/lib/CodeGen/StackMaps.cpp b/lib/CodeGen/StackMaps.cpp index 6d0c165c8f6..29ff0475a4e 100644 --- a/lib/CodeGen/StackMaps.cpp +++ b/lib/CodeGen/StackMaps.cpp @@ -68,10 +68,10 @@ unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const { std::pair StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI, - MachineInstr::const_mop_iterator MOE) const { + MachineInstr::const_mop_iterator MOE) { const MachineOperand &MOP = *MOI; - assert((!MOP.isReg() || !MOP.isImplicit()) && - "Implicit operands should not be processed."); + assert(!MOP.isRegMask() && (!MOP.isReg() || !MOP.isImplicit()) && + "Register mask and implicit operands should not be processed."); if (MOP.isImm()) { // Verify anyregcc @@ -106,9 +106,6 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI, } } - if (MOP.isRegMask() || MOP.isRegLiveOut()) - return std::make_pair(Location(), ++MOI); - // Otherwise this is a reg operand. The physical register number will // ultimately be encoded as a DWARF regno. The stack map also records the size // of a spill slot that can hold the register content. (The runtime can @@ -123,66 +120,6 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI, Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI); } -/// Go up the super-register chain until we hit a valid dwarf register number. -static short getDwarfRegNum(unsigned Reg, const MCRegisterInfo &MCRI, - const TargetRegisterInfo *TRI) { - int RegNo = MCRI.getDwarfRegNum(Reg, false); - for (MCSuperRegIterator SR(Reg, TRI); - SR.isValid() && RegNo < 0; ++SR) - RegNo = TRI->getDwarfRegNum(*SR, false); - - assert(RegNo >= 0 && "Invalid Dwarf register number."); - return (unsigned short) RegNo; -} - -/// Create a live-out register record for the given register Reg. -StackMaps::LiveOutReg -StackMaps::createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI, - const TargetRegisterInfo *TRI) const { - unsigned RegNo = getDwarfRegNum(Reg, MCRI, TRI); - unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize(); - unsigned LLVMRegNo = MCRI.getLLVMRegNum(RegNo, false); - unsigned SubRegIdx = MCRI.getSubRegIndex(LLVMRegNo, Reg); - unsigned Offset = 0; - if (SubRegIdx) - Offset = MCRI.getSubRegIdxOffset(SubRegIdx) / 8; - - return LiveOutReg(Reg, RegNo, Offset + Size); -} - -/// Parse the register live-out mask and return a vector of live-out registers -/// that need to be recorded in the stackmap. -StackMaps::LiveOutVec -StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const { - assert(Mask && "No register mask specified"); - const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo(); - MCContext &OutContext = AP.OutStreamer.getContext(); - const MCRegisterInfo &MCRI = *OutContext.getRegisterInfo(); - LiveOutVec LiveOuts; - - for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg) - if ((Mask[Reg / 32] >> Reg % 32) & 1) - LiveOuts.push_back(createLiveOutReg(Reg, MCRI, TRI)); - - std::sort(LiveOuts.begin(), LiveOuts.end()); - for (LiveOutVec::iterator I = LiveOuts.begin(), E = LiveOuts.end(); - I != E; ++I) { - if (!I->Reg) - continue; - for (LiveOutVec::iterator II = next(I); II != E; ++II) { - if (I->RegNo != II->RegNo) - break; - I->Size = std::max(I->Size, II->Size); - if (TRI->isSuperRegister(I->Reg, II->Reg)) - I->Reg = II->Reg; - II->Reg = 0; - } - } - LiveOuts.erase(std::remove_if(LiveOuts.begin(), LiveOuts.end(), - LiveOutReg::isInvalid), LiveOuts.end()); - return LiveOuts; -} - void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, MachineInstr::const_mop_iterator MOI, MachineInstr::const_mop_iterator MOE, @@ -192,8 +129,7 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, MCSymbol *MILabel = OutContext.CreateTempSymbol(); AP.OutStreamer.EmitLabel(MILabel); - LocationVec Locations; - LiveOutVec LiveOuts; + LocationVec CallsiteLocs; if (recordResult) { std::pair ParseResult = @@ -202,7 +138,7 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, Location &Loc = ParseResult.first; assert(Loc.LocType == Location::Register && "Stackmap return location must be a register."); - Locations.push_back(Loc); + CallsiteLocs.push_back(Loc); } while (MOI != MOE) { @@ -215,9 +151,7 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, Loc.Offset = ConstPool.getConstantIndex(Loc.Offset); } - // Skip the register mask and register live-out mask - if (Loc.LocType != Location::Unprocessed) - Locations.push_back(Loc); + CallsiteLocs.push_back(Loc); } const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub( @@ -225,23 +159,21 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, MCSymbolRefExpr::Create(AP.CurrentFnSym, OutContext), OutContext); - if (MOI->isRegLiveOut()) - LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut()); - - CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, Locations, LiveOuts)); + CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, CallsiteLocs)); } static MachineInstr::const_mop_iterator getStackMapEndMOP(MachineInstr::const_mop_iterator MOI, MachineInstr::const_mop_iterator MOE) { for (; MOI != MOE; ++MOI) - if (MOI->isRegLiveOut() || (MOI->isReg() && MOI->isImplicit())) + if (MOI->isRegMask() || (MOI->isReg() && MOI->isImplicit())) break; + return MOI; } void StackMaps::recordStackMap(const MachineInstr &MI) { - assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap"); + assert(MI.getOpcode() == TargetOpcode::STACKMAP && "exected stackmap"); int64_t ID = MI.getOperand(0).getImm(); recordStackMapOpers(MI, ID, llvm::next(MI.operands_begin(), 2), @@ -250,7 +182,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI) { } void StackMaps::recordPatchPoint(const MachineInstr &MI) { - assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint"); + assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "exected stackmap"); PatchPointOpers opers(&MI); int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm(); @@ -289,11 +221,6 @@ void StackMaps::recordPatchPoint(const MachineInstr &MI) { /// uint16 : Dwarf RegNum /// int32 : Offset /// } -/// uint16 : NumLiveOuts -/// LiveOuts[NumLiveOuts] -/// uint16 : Dwarf RegNum -/// uint8 : Reserved -/// uint8 : Size in Bytes /// } /// /// Location Encoding, Type, Value: @@ -346,7 +273,6 @@ void StackMaps::serializeToStackMapSection() { uint64_t CallsiteID = CSII->ID; const LocationVec &CSLocs = CSII->Locations; - const LiveOutVec &LiveOuts = CSII->LiveOuts; DEBUG(dbgs() << WSMP << "callsite " << CallsiteID << "\n"); @@ -354,12 +280,11 @@ void StackMaps::serializeToStackMapSection() { // runtime than crash in case of in-process compilation. Currently, we do // simple overflow checks, but we may eventually communicate other // compilation errors this way. - if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) { - AP.OutStreamer.EmitIntValue(UINT64_MAX, 8); // Invalid ID. + if (CSLocs.size() > UINT16_MAX) { + AP.OutStreamer.EmitIntValue(UINT32_MAX, 8); // Invalid ID. AP.OutStreamer.EmitValue(CSII->CSOffsetExpr, 4); AP.OutStreamer.EmitIntValue(0, 2); // Reserved. AP.OutStreamer.EmitIntValue(0, 2); // 0 locations. - AP.OutStreamer.EmitIntValue(0, 2); // 0 live-out registers. continue; } @@ -436,24 +361,6 @@ void StackMaps::serializeToStackMapSection() { AP.OutStreamer.EmitIntValue(RegNo, 2); AP.OutStreamer.EmitIntValue(Offset, 4); } - - DEBUG(dbgs() << WSMP << " has " << LiveOuts.size() - << " live-out registers\n"); - - AP.OutStreamer.EmitIntValue(LiveOuts.size(), 2); - - operIdx = 0; - for (LiveOutVec::const_iterator LI = LiveOuts.begin(), LE = LiveOuts.end(); - LI != LE; ++LI, ++operIdx) { - DEBUG(dbgs() << WSMP << " LO " << operIdx << ": " - << MCRI.getName(LI->Reg) - << " [encoding: .short " << LI->RegNo - << ", .byte 0, .byte " << LI->Size << "]\n"); - - AP.OutStreamer.EmitIntValue(LI->RegNo, 2); - AP.OutStreamer.EmitIntValue(0, 1); - AP.OutStreamer.EmitIntValue(LI->Size, 1); - } } AP.OutStreamer.AddBlankLine(); diff --git a/test/CodeGen/X86/stackmap-liveness.ll b/test/CodeGen/X86/stackmap-liveness.ll deleted file mode 100644 index 4930302b949..00000000000 --- a/test/CodeGen/X86/stackmap-liveness.ll +++ /dev/null @@ -1,85 +0,0 @@ -; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -disable-fp-elim | FileCheck %s -; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -disable-fp-elim -enable-stackmap-liveness| FileCheck -check-prefix=LIVE %s -; -; Note: Print verbose stackmaps using -debug-only=stackmaps. - -; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps -; CHECK-NEXT: __LLVM_StackMaps: -; CHECK-NEXT: .long 0 -; Num LargeConstants -; CHECK-NEXT: .long 0 -; Num Callsites -; CHECK-NEXT: .long 3 - -; CHECK-LABEL: .long L{{.*}}-_liveness -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 0 -; LIVE-LABEL: .long L{{.*}}-_liveness -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .short 2 -; LIVE-NEXT: .short 7 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 8 -; LIVE-NEXT: .short 19 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 16 - -; CHECK-LABEL: .long L{{.*}}-_liveness -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 0 -; LIVE-LABEL: .long L{{.*}}-_liveness -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .short 6 -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 2 -; LIVE-NEXT: .short 7 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 8 -; LIVE-NEXT: .short 8 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 8 -; LIVE-NEXT: .short 17 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 32 -; LIVE-NEXT: .short 18 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 32 -; LIVE-NEXT: .short 19 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 16 - -; CHECK-LABEL: .long L{{.*}}-_liveness -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 0 -; LIVE-LABEL: .long L{{.*}}-_liveness -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .short 0 -; LIVE-NEXT: .short 2 -; LIVE-NEXT: .short 7 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 8 -; LIVE-NEXT: .short 19 -; LIVE-NEXT: .byte 0 -; LIVE-NEXT: .byte 16 -define void @liveness() { -entry: - %a1 = call <2 x double> asm sideeffect "", "={xmm2}"() nounwind - call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 1, i32 5) - %a2 = call i64 asm sideeffect "", "={r8}"() nounwind - %a3 = call i8 asm sideeffect "", "={ah}"() nounwind - %a4 = call <4 x double> asm sideeffect "", "={ymm0}"() nounwind - %a5 = call <4 x double> asm sideeffect "", "={ymm1}"() nounwind - call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 2, i32 5) - call void asm sideeffect "", "{r8},{ah},{ymm0},{ymm1}"(i64 %a2, i8 %a3, <4 x double> %a4, <4 x double> %a5) nounwind - call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 3, i32 5) - call void asm sideeffect "", "{xmm2}"(<2 x double> %a1) nounwind - ret void -} - -declare void @llvm.experimental.stackmap(i64, i32, ...) diff --git a/test/CodeGen/X86/stackmap.ll b/test/CodeGen/X86/stackmap.ll index e4194adfaa4..e0cb7589c4f 100644 --- a/test/CodeGen/X86/stackmap.ll +++ b/test/CodeGen/X86/stackmap.ll @@ -183,15 +183,15 @@ entry: ; ; Verify 17 stack map entries. ; -; CHECK-LABEL: .long L{{.*}}-_spilledValue -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 17 +; CHECK-LABEL:.long L{{.*}}-_spilledValue +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 17 ; ; Check that at least one is a spilled entry from RBP. ; Location: Indirect RBP + ... -; CHECK: .byte 3 -; CHECK-NEXT: .byte 8 -; CHECK-NEXT: .short 6 +; CHECK: .byte 3 +; CHECK-NEXT: .byte 8 +; CHECK-NEXT: .short 6 define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) { entry: call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 11, i32 15, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) @@ -202,15 +202,15 @@ entry: ; ; Verify 17 stack map entries. ; -; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .short 17 +; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 17 ; ; Check that at least one is a spilled entry from RBP. ; Location: Indirect RBP + ... -; CHECK: .byte 3 -; CHECK-NEXT: .byte 8 -; CHECK-NEXT: .short 6 +; CHECK: .byte 3 +; CHECK-NEXT: .byte 8 +; CHECK-NEXT: .short 6 define webkit_jscc void @spilledStackMapValue(i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) { entry: call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 12, i32 15, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16) @@ -219,16 +219,16 @@ entry: ; Spill a subregister stackmap operand. ; -; CHECK-LABEL: .long L{{.*}}-_spillSubReg -; CHECK-NEXT: .short 0 +; CHECK-LABEL: .long L{{.*}}-_spillSubReg +; CHECK-NEXT: .short 0 ; 4 locations -; CHECK-NEXT: .short 1 +; CHECK-NEXT: .short 1 ; ; Check that the subregister operand is a 4-byte spill. ; Location: Indirect, 4-byte, RBP + ... -; CHECK: .byte 3 -; CHECK-NEXT: .byte 4 -; CHECK-NEXT: .short 6 +; CHECK: .byte 3 +; CHECK-NEXT: .byte 4 +; CHECK-NEXT: .short 6 define void @spillSubReg(i64 %arg) #0 { bb: br i1 undef, label %bb1, label %bb2 @@ -259,23 +259,23 @@ bb61: ; Map a single byte subregister. There is no DWARF register number, so ; we expect the register to be encoded with the proper size and spill offset. We don't know which ; -; CHECK-LABEL: .long L{{.*}}-_subRegOffset -; CHECK-NEXT: .short 0 +; CHECK-LABEL: .long L{{.*}}-_subRegOffset +; CHECK-NEXT: .short 0 ; 2 locations -; CHECK-NEXT: .short 2 +; CHECK-NEXT: .short 2 ; ; Check that the subregister operands are 1-byte spills. ; Location 0: Register, 4-byte, AL -; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .short 0 -; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .long 0 ; ; Location 1: Register, 4-byte, BL -; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .short 3 -; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .short 3 +; CHECK-NEXT: .long 0 define void @subRegOffset(i16 %arg) { %v = mul i16 %arg, 5 %a0 = trunc i16 %v to i8 @@ -289,10 +289,10 @@ define void @subRegOffset(i16 %arg) { ; Map a constant value. ; -; CHECK-LABEL: .long L{{.*}}-_liveConstant -; CHECK-NEXT: .short 0 +; CHECK-LABEL: .long L{{.*}}-_liveConstant +; CHECK-NEXT: .short 0 ; 1 location -; CHECK-NEXT: .short 1 +; CHECK-NEXT: .short 1 ; Loc 0: SmallConstant ; CHECK-NEXT: .byte 4 ; CHECK-NEXT: .byte 8 @@ -316,9 +316,9 @@ define void @liveConstant() { ; CHECK-NEXT: .byte 8 ; CHECK-NEXT: .short 6 ; CHECK-NEXT: .long - +; CHECK-NEXT: .quad ; Callsite 17 -; CHECK-LABEL: .long L{{.*}}-_directFrameIdx +; CHECK-NEXT: .long L{{.*}}-_directFrameIdx ; CHECK-NEXT: .short 0 ; 2 locations ; CHECK-NEXT: .short 2