[llvm-commits] [llvm] r57722 - in /llvm/trunk: include/llvm/Target/TargetInstrDesc.h utils/TableGen/InstrInfoEmitter.cpp utils/TableGen/InstrInfoEmitter.h

Evan Cheng evan.cheng at apple.com
Fri Oct 17 14:00:09 PDT 2008


Author: evancheng
Date: Fri Oct 17 16:00:09 2008
New Revision: 57722

URL: http://llvm.org/viewvc/llvm-project?rev=57722&view=rev
Log:
Add RCBarriers to TargetInstrDesc. It's a list of register classes the given instruction can "clobber". For example, on x86 the call instruction can modify all of the XMM and fp stack registers.

TableGen has been taught to generate the lists from instruction definitions.

Modified:
    llvm/trunk/include/llvm/Target/TargetInstrDesc.h
    llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
    llvm/trunk/utils/TableGen/InstrInfoEmitter.h

Modified: llvm/trunk/include/llvm/Target/TargetInstrDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrDesc.h?rev=57722&r1=57721&r2=57722&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetInstrDesc.h (original)
+++ llvm/trunk/include/llvm/Target/TargetInstrDesc.h Fri Oct 17 16:00:09 2008
@@ -19,6 +19,8 @@
 
 namespace llvm {
 
+class TargetRegisterClass;
+
 //===----------------------------------------------------------------------===//
 // Machine Operand Flags and Description
 //===----------------------------------------------------------------------===//
@@ -107,16 +109,17 @@
 /// points to this struct directly to describe itself.
 class TargetInstrDesc {
 public:
-  unsigned short  Opcode;        // The opcode number.
+  unsigned short  Opcode;        // The opcode number
   unsigned short  NumOperands;   // Num of args (may be more if variable_ops)
-  unsigned short  NumDefs;       // Num of args that are definitions.
+  unsigned short  NumDefs;       // Num of args that are definitions
   unsigned short  SchedClass;    // enum identifying instr sched class
-  const char *    Name;          // Name of the instruction record in td file.
-  unsigned        Flags;         // flags identifying machine instr class
+  const char *    Name;          // Name of the instruction record in td file
+  unsigned        Flags;         // Flags identifying machine instr class
   unsigned        TSFlags;       // Target Specific Flag values
   const unsigned *ImplicitUses;  // Registers implicitly read by this instr
   const unsigned *ImplicitDefs;  // Registers implicitly defined by this instr
-  const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands.
+  const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered"
+  const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands
 
   /// getOperandConstraint - Returns the value of the specific constraint if
   /// it is set. Returns -1 if it is not set.
@@ -202,6 +205,17 @@
     return ImplicitDefs;
   }
 
+  /// getRegClassBarriers - Return a list of register classes that are
+  /// completely clobbered by this machine instruction. For example, on X86
+  /// the call instructions will completely clobber all the registers in the
+  /// fp stack and XMM classes.
+  ///
+  /// This method returns null if the instruction doesn't completely clobber
+  /// any register class.
+  const TargetRegisterClass **getRegClassBarriers() const {
+    return RCBarriers;
+  }
+
   /// getSchedClass - Return the scheduling class for this instruction.  The
   /// scheduling class is an index into the InstrItineraryData table.  This
   /// returns zero if there is no known scheduling information for the

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=57722&r1=57721&r2=57722&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Fri Oct 17 16:00:09 2008
@@ -27,6 +27,14 @@
   OS << "0 };\n";
 }
 
+static void PrintBarriers(std::vector<Record*> &Barriers,
+                          unsigned Num, std::ostream &OS) {
+  OS << "static const TargetRegisterClass* Barriers" << Num << "[] = { ";
+  for (unsigned i = 0, e = Barriers.size(); i != e; ++i)
+    OS << "&" << getQualifiedName(Barriers[i]) << "RegClass, ";
+  OS << "NULL };\n";
+}
+
 //===----------------------------------------------------------------------===//
 // Instruction Itinerary Information.
 //===----------------------------------------------------------------------===//
@@ -137,6 +145,33 @@
   }
 }
 
+void InstrInfoEmitter::DetectRegisterClassBarriers(std::vector<Record*> &Defs,
+                                  const std::vector<CodeGenRegisterClass> &RCs,
+                                  std::vector<Record*> &Barriers) {
+  std::set<Record*> DefSet;
+  unsigned NumDefs = Defs.size();
+  for (unsigned i = 0; i < NumDefs; ++i)
+    DefSet.insert(Defs[i]);
+
+  for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
+    const CodeGenRegisterClass &RC = RCs[i];
+    unsigned NumRegs = RC.Elements.size();
+    if (NumRegs > NumDefs)
+      continue; // Can't possibly clobber this RC.
+
+    bool Clobber = true;
+    for (unsigned j = 0; j < NumRegs; ++j) {
+      Record *Reg = RC.Elements[j];
+      if (!DefSet.count(Reg)) {
+        Clobber = false;
+        break;
+      }
+    }
+    if (Clobber)
+      Barriers.push_back(RC.TheDef);
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // Main Output.
 //===----------------------------------------------------------------------===//
@@ -151,10 +186,14 @@
   CodeGenTarget &Target = CDP.getTargetInfo();
   const std::string &TargetName = Target.getName();
   Record *InstrInfo = Target.getInstructionSet();
+  const std::vector<CodeGenRegisterClass> &RCs = Target.getRegisterClasses();
 
   // Keep track of all of the def lists we have emitted already.
   std::map<std::vector<Record*>, unsigned> EmittedLists;
   unsigned ListNumber = 0;
+  std::map<std::vector<Record*>, unsigned> EmittedBarriers;
+  unsigned BarrierNumber = 0;
+  std::map<Record*, unsigned> BarriersMap;
  
   // Emit all of the instruction's implicit uses and defs.
   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
@@ -167,6 +206,14 @@
     }
     std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
     if (!Defs.empty()) {
+      std::vector<Record*> RCBarriers;
+      DetectRegisterClassBarriers(Defs, RCs, RCBarriers);
+      if (!RCBarriers.empty()) {
+        unsigned &IB = EmittedBarriers[RCBarriers];
+        if (!IB) PrintBarriers(RCBarriers, IB = ++BarrierNumber, OS);
+        BarriersMap.insert(std::make_pair(Inst, IB));
+      }
+
       unsigned &IL = EmittedLists[Defs];
       if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS);
     }
@@ -186,7 +233,7 @@
 
   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i)
     emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists,
-               OperandInfoIDs, OS);
+               BarriersMap, OperandInfoIDs, OS);
   OS << "};\n";
   OS << "} // End llvm namespace \n";
 }
@@ -194,6 +241,7 @@
 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                                   Record *InstrInfo,
                          std::map<std::vector<Record*>, unsigned> &EmittedLists,
+                                  std::map<Record*, unsigned> &BarriersMap,
                                   const OperandInfoMapTy &OpInfo,
                                   std::ostream &OS) {
   int MinOperands = 0;
@@ -257,6 +305,12 @@
   else
     OS << "ImplicitList" << EmittedLists[DefList] << ", ";
 
+  std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef);
+  if (BI == BarriersMap.end())
+    OS << "NULL, ";
+  else
+    OS << "Barriers" << BI->second << ", ";
+
   // Emit the operand info.
   std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
   if (OperandInfo.empty())

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.h?rev=57722&r1=57721&r2=57722&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.h (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.h Fri Oct 17 16:00:09 2008
@@ -44,6 +44,7 @@
   void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                   Record *InstrInfo, 
                   std::map<std::vector<Record*>, unsigned> &EL,
+                  std::map<Record*, unsigned> &BM,
                   const OperandInfoMapTy &OpInfo,
                   std::ostream &OS);
   void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift,
@@ -56,6 +57,10 @@
   // Operand information.
   void EmitOperandInfo(std::ostream &OS, OperandInfoMapTy &OperandInfoIDs);
   std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
+
+  void DetectRegisterClassBarriers(std::vector<Record*> &Defs,
+                                   const std::vector<CodeGenRegisterClass> &RCs,
+                                   std::vector<Record*> &Barriers);
 };
 
 } // End llvm namespace





More information about the llvm-commits mailing list