]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
[Stackmap] Refactor operand parsing.
authorJuergen Ributzka <juergen@apple.com>
Sat, 14 Dec 2013 23:06:19 +0000 (23:06 +0000)
committerJuergen Ributzka <juergen@apple.com>
Sat, 14 Dec 2013 23:06:19 +0000 (23:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197329 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/StackMaps.h
lib/CodeGen/StackMaps.cpp

index 40de34fdc6321daee71db25e7ede238309d5660a..508606ac9babece27b48a11647747960bbb9d029 100644 (file)
@@ -171,9 +171,10 @@ private:
   CallsiteInfoList CSInfos;
   ConstantPool ConstPool;
 
-  std::pair<Location, MachineInstr::const_mop_iterator>
+  MachineInstr::const_mop_iterator
   parseOperand(MachineInstr::const_mop_iterator MOI,
-               MachineInstr::const_mop_iterator MOE) const;
+               MachineInstr::const_mop_iterator MOE,
+               LocationVec &Locs, LiveOutVec &LiveOuts) const;
 
   /// \brief Create a live-out register record for the given register @p Reg.
   LiveOutReg createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI,
index 8f6972d60f27a2e3331d2a02b96087725000a28c..19abcfd36ef7f2aa954be34a34bda705e8f4c5a6 100644 (file)
 
 using namespace llvm;
 
-PatchPointOpers::PatchPointOpers(const MachineInstr *MI):
-  MI(MI),
-  HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
-         !MI->getOperand(0).isImplicit()),
-  IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == CallingConv::AnyReg) {
-
+PatchPointOpers::PatchPointOpers(const MachineInstr *MI)
+  MI(MI),
+    HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
+           !MI->getOperand(0).isImplicit()),
+    IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == CallingConv::AnyReg)
+{
 #ifndef NDEBUG
-  {
   unsigned CheckStartIdx = 0, e = MI->getNumOperands();
   while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() &&
          MI->getOperand(CheckStartIdx).isDef() &&
@@ -45,7 +44,6 @@ PatchPointOpers::PatchPointOpers(const MachineInstr *MI):
 
   assert(getMetaIdx() == CheckStartIdx &&
          "Unexpected additonal definition in Patchpoint intrinsic.");
-  }
 #endif
 }
 
@@ -66,61 +64,64 @@ unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
   return ScratchIdx;
 }
 
-std::pair<StackMaps::Location, MachineInstr::const_mop_iterator>
+MachineInstr::const_mop_iterator
 StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
-                        MachineInstr::const_mop_iterator MOE) const {
-  const MachineOperand &MOP = *MOI;
-  assert((!MOP.isReg() || !MOP.isImplicit()) &&
-         "Implicit operands should not be processed.");
-
-  if (MOP.isImm()) {
-    // Verify anyregcc
-    // [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
-
-    switch (MOP.getImm()) {
-      default: llvm_unreachable("Unrecognized operand type.");
-      case StackMaps::DirectMemRefOp: {
-        unsigned Size = AP.TM.getDataLayout()->getPointerSizeInBits();
-        assert((Size % 8) == 0 && "Need pointer size in bytes.");
-        Size /= 8;
-        unsigned Reg = (++MOI)->getReg();
-        int64_t Imm = (++MOI)->getImm();
-        return std::make_pair(
-          Location(StackMaps::Location::Direct, Size, Reg, Imm), ++MOI);
-      }
-      case StackMaps::IndirectMemRefOp: {
-        int64_t Size = (++MOI)->getImm();
-        assert(Size > 0 && "Need a valid size for indirect memory locations.");
-        unsigned Reg = (++MOI)->getReg();
-        int64_t Imm = (++MOI)->getImm();
-        return std::make_pair(
-          Location(StackMaps::Location::Indirect, Size, Reg, Imm), ++MOI);
-      }
-      case StackMaps::ConstantOp: {
-        ++MOI;
-        assert(MOI->isImm() && "Expected constant operand.");
-        int64_t Imm = MOI->getImm();
-        return std::make_pair(
-          Location(Location::Constant, sizeof(int64_t), 0, Imm), ++MOI);
-      }
+                        MachineInstr::const_mop_iterator MOE,
+                        LocationVec &Locs, LiveOutVec &LiveOuts) const {
+  if (MOI->isImm()) {
+    switch (MOI->getImm()) {
+    default: llvm_unreachable("Unrecognized operand type.");
+    case StackMaps::DirectMemRefOp: {
+      unsigned Size = AP.TM.getDataLayout()->getPointerSizeInBits();
+      assert((Size % 8) == 0 && "Need pointer size in bytes.");
+      Size /= 8;
+      unsigned Reg = (++MOI)->getReg();
+      int64_t Imm = (++MOI)->getImm();
+      Locs.push_back(Location(StackMaps::Location::Direct, Size, Reg, Imm));
+      break;
     }
+    case StackMaps::IndirectMemRefOp: {
+      int64_t Size = (++MOI)->getImm();
+      assert(Size > 0 && "Need a valid size for indirect memory locations.");
+      unsigned Reg = (++MOI)->getReg();
+      int64_t Imm = (++MOI)->getImm();
+      Locs.push_back(Location(StackMaps::Location::Indirect, Size, Reg, Imm));
+      break;
+    }
+    case StackMaps::ConstantOp: {
+      ++MOI;
+      assert(MOI->isImm() && "Expected constant operand.");
+      int64_t Imm = MOI->getImm();
+      Locs.push_back(Location(Location::Constant, sizeof(int64_t), 0, Imm));
+      break;
+    }
+    }
+    return ++MOI;
+  }
+
+  // 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 track the actual size of the data type
+  // if it needs to.)
+  if (MOI->isReg()) {
+    // Skip implicit registers (this includes our scratch registers)
+    if (MOI->isImplicit())
+      return ++MOI;
+
+    assert(TargetRegisterInfo::isPhysicalRegister(MOI->getReg()) &&
+           "Virtreg operands should have been rewritten before now.");
+    const TargetRegisterClass *RC =
+      AP.TM.getRegisterInfo()->getMinimalPhysRegClass(MOI->getReg());
+    assert(!MOI->getSubReg() && "Physical subreg still around.");
+    Locs.push_back(
+      Location(Location::Register, RC->getSize(), MOI->getReg(), 0));
+    return ++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
-  // track the actual size of the data type if it needs to.)
-  assert(MOP.isReg() && "Expected register operand here.");
-  assert(TargetRegisterInfo::isPhysicalRegister(MOP.getReg()) &&
-         "Virtreg operands should have been rewritten before now.");
-  const TargetRegisterClass *RC =
-    AP.TM.getRegisterInfo()->getMinimalPhysRegClass(MOP.getReg());
-  assert(!MOP.getSubReg() && "Physical subreg still around.");
-  return std::make_pair(
-    Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI);
+  if (MOI->isRegLiveOut())
+    LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
+
+  return ++MOI;
 }
 
 /// Go up the super-register chain until we hit a valid dwarf register number.
@@ -195,28 +196,23 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
   LiveOutVec LiveOuts;
 
   if (recordResult) {
-    std::pair<Location, MachineInstr::const_mop_iterator> ParseResult =
-      parseOperand(MI.operands_begin(), llvm::next(MI.operands_begin()));
-
-    Location &Loc = ParseResult.first;
-    assert(Loc.LocType == Location::Register &&
-           "Stackmap return location must be a register.");
-    Locations.push_back(Loc);
+    assert(PatchPointOpers(&MI).hasDef() && "Stackmap has no return value.");
+    parseOperand(MI.operands_begin(), llvm::next(MI.operands_begin()),
+                 Locations, LiveOuts);
   }
 
+  // Parse operands.
   while (MOI != MOE) {
-    Location Loc;
-    tie(Loc, MOI) = parseOperand(MOI, MOE);
+    MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
+  }
 
-    // Move large constants into the constant pool.
-    if (Loc.LocType == Location::Constant && (Loc.Offset & ~0xFFFFFFFFULL)) {
-      Loc.LocType = Location::ConstantIndex;
-      Loc.Offset = ConstPool.getConstantIndex(Loc.Offset);
+  // Move large constants into the constant pool.
+  for (LocationVec::iterator I = Locations.begin(), E = Locations.end();
+       I != E; ++I) {
+    if (I->LocType == Location::Constant && (I->Offset & ~0xFFFFFFFFULL)) {
+      I->LocType = Location::ConstantIndex;
+      I->Offset = ConstPool.getConstantIndex(I->Offset);
     }
-
-    // Skip the register mask and register live-out mask
-    if (Loc.LocType != Location::Unprocessed)
-      Locations.push_back(Loc);
   }
 
   const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub(
@@ -224,28 +220,15 @@ 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));
 }
 
-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()))
-      break;
-  return MOI;
-}
-
 void StackMaps::recordStackMap(const MachineInstr &MI) {
   assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
 
   int64_t ID = MI.getOperand(0).getImm();
   recordStackMapOpers(MI, ID, llvm::next(MI.operands_begin(), 2),
-                      getStackMapEndMOP(MI.operands_begin(),
-                                        MI.operands_end()));
+                      MI.operands_end());
 }
 
 void StackMaps::recordPatchPoint(const MachineInstr &MI) {
@@ -256,7 +239,7 @@ void StackMaps::recordPatchPoint(const MachineInstr &MI) {
 
   MachineInstr::const_mop_iterator MOI =
     llvm::next(MI.operands_begin(), opers.getStackMapStartIdx());
-  recordStackMapOpers(MI, ID, MOI, getStackMapEndMOP(MOI, MI.operands_end()),
+  recordStackMapOpers(MI, ID, MOI, MI.operands_end(),
                       opers.isAnyReg() && opers.hasDef());
 
 #ifndef NDEBUG