[llvm-commits] PATCH: Tablegen - Add HWEncoding field to Register class and generate getHWEncoding() function

Tom Stellard thomas.stellard at amd.com
Mon May 14 12:34:11 PDT 2012


On Mon, May 14, 2012 at 10:47:00AM -0700, Jim Grosbach wrote:
> 
> On May 10, 2012, at 8:11 AM, Tom Stellard <thomas.stellard at amd.com> wrote:
> 
> > On Tue, May 08, 2012 at 09:25:40AM -0700, Jim Grosbach wrote:
> >> 
> >> On May 8, 2012, at 7:09 AM, Tom Stellard <thomas.stellard at amd.com> wrote:
> >> 
> >>> Hi Jim,
> >>> 
> >>> Thanks for the feedback.
> >>> 
> >>> On Mon, May 07, 2012 at 03:59:51PM -0700, Jim Grosbach wrote:
> >>>> Hi Tom,
> >>>> 
> >>>> Good idea. ARM could use this, too.
> >>>> 
> >>>> The function shouldn't go into the <Target>GenRegisterInfo class, though. That's derived from TargetRegisterInfo, which is part of the Target layer. The code layers that will want to access this information, at least for the most part, are part of the MC layer and can't access that. In particular, the <Target>MCCodeEmitter bits want this and can't hook into Target classes. It could be made a lookup table and hooked in MCRegisterInfo as a generic function w/ TableGen'erated data payload, perhaps. That would require teaching the MCCodeEmitter how to get access to the MCRegisterInfo instance. There was a recent patch to do that for the InstPrinter that would provide an example of the sorts of things needed for that. TargetRegisterInfo derives from MCRegisterInfo, so anything in the Target layer that actually wants the encoding bits for a register could still get to them that way.
> >>>> 
> >>> 
> >>> I'm not really familiar with the MC layer, so I need to spend some time
> >>> learning about it before I can come up with a new patch.  Is this more
> >>> or less what you are suggesting that I do:
> >>> 
> >>> 1. Have tablegen generate a lookup table for registers and their
> >>>  encodings.
> >>> 2. Add an extra parameter to InitMCRegisterInfo for the new lookup table
> >>> 3. Add a function to the MCRegisterInfo class called getHWEncoding() (or
> >>>  something similar) that uses the new lookup table.
> >>> 4. Teach MCCodeEmitter how to access MCRegisterInfo.
> >> 
> >> Yep, that's it exactly. I would probably name the function something like getEncodingValue() instead, but that's purely stylistic and not a big deal.
> >> 
> > 
> > Hi,
> > 
> > I've split these changes into two patches. The first patch,
> > tablegen-gen-reg-hw-encoding-v2.patch causes tablegen to generate a
> > lookup table that maps registers to their encodings and adds an accessor
> > for the lookup table to MCRegisterInfo.
> > 
> 
> Looks good. A couple of small details.
> 
> The number of physical registers for a target is limited to 64k, so we can use a 16-bit value for entries in the table and for the bitfield in the .td file. The exception is the external interface (getEncodingValue()), which should stay w/ a 32-bit input so the assert() can do its job of detecting virtual regs that somehow lived past their expiration date.
> 
> +    uint64_t Value = 0;
> +    for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
> +        if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(b)))
> +        Value |= (uint64_t)B->getValue() << b;
> +    }
> 
> Only need two spaces of indentation in the body of the 'for' loop here.
>

Hi,

I've attached a new patch tablegen-gen-reg-hw-encoding-v3.patch with
these fixes.  I don't have commit access, so I'll need someone to commit
these for me.

-Tom
 
> > The second patch, teach-MCCodeEmitter-about-MCRegisterInfo.patch
> > allows MCCodeEmitters to access a target's MCRegisterInfo.  I wasn't
> > sure if I should add an MCRegisterInfo member to MCCodeEmitter or if
> > it was sufficent to just pass a MCRegisterInfo parameter to all the
> > create*MCCodeEmitter functions.  This patch implements the latter
> > solution, but I can change it if you would prefer the former.
> > 
> 
> I think this is fine. It's consistent with how we deal with MCInstrInfo, anyway. We can change both in a later patch if need be.
> 
> Regards,
>   Jim
> 
> 
> > -Tom
> > 
> > <tablegen-gen-reg-hw-encoding-v2.patch><teach-MCCodeEmitter-about-MCRegisterInfo.patch>
> 
> 
-------------- next part --------------
diff --git include/llvm/MC/MCRegisterInfo.h include/llvm/MC/MCRegisterInfo.h
index 27acf2f..47f5749 100644
--- include/llvm/MC/MCRegisterInfo.h
+++ include/llvm/MC/MCRegisterInfo.h
@@ -146,6 +146,8 @@ private:
   const uint16_t *SubRegIndices;              // Pointer to the subreg lookup
                                               // array.
   unsigned NumSubRegIndices;                  // Number of subreg indices.
+  const uint16_t *RegEncodingTable;           // Pointer to array of register
+                                              // encodings.
 
   unsigned L2DwarfRegsSize;
   unsigned EHL2DwarfRegsSize;
@@ -164,7 +166,8 @@ public:
                           const MCRegisterClass *C, unsigned NC,
                           const uint16_t *RL,
                           const uint16_t *SubIndices,
-                          unsigned NumIndices) {
+                          unsigned NumIndices,
+                          const uint16_t *RET) {
     Desc = D;
     NumRegs = NR;
     RAReg = RA;
@@ -173,6 +176,7 @@ public:
     NumClasses = NC;
     SubRegIndices = SubIndices;
     NumSubRegIndices = NumIndices;
+    RegEncodingTable = RET;
   }
 
   /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf
@@ -354,6 +358,14 @@ public:
     assert(i < getNumRegClasses() && "Register Class ID out of range");
     return Classes[i];
   }
+
+   /// getEncodingValue - Returns the encoding for RegNo
+  uint16_t getEncodingValue(unsigned RegNo) const {
+    assert(RegNo < NumRegs &&
+           "Attempting to get encoding for invalid register number!");
+    return RegEncodingTable[RegNo];
+  }
+
 };
 
 } // End llvm namespace
diff --git include/llvm/Target/Target.td include/llvm/Target/Target.td
index bd959d0..1f2bd47 100644
--- include/llvm/Target/Target.td
+++ include/llvm/Target/Target.td
@@ -96,6 +96,9 @@ class Register<string n, list<string> altNames = []> {
   // x86 register AX is covered by its sub-registers AL and AH, but EAX is not
   // covered by its sub-register AX.
   bit CoveredBySubRegs = 0;
+
+  // HWEncoding - The target specific hardware encoding for this register.
+  bits<16> HWEncoding = 0;
 }
 
 // RegisterWithSubRegs - This can be used to define instances of Register which
diff --git utils/TableGen/RegisterInfoEmitter.cpp utils/TableGen/RegisterInfoEmitter.cpp
index 5b4a876..98bb611 100644
--- utils/TableGen/RegisterInfoEmitter.cpp
+++ utils/TableGen/RegisterInfoEmitter.cpp
@@ -636,6 +636,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
 
   EmitRegMappingTables(OS, Regs, false);
 
+  // Emit Reg encoding table
+  OS << "extern const uint16_t " << TargetName;
+  OS << "RegEncodingTable[] = {\n";
+  // Add entry for NoRegister
+  OS << "  0,\n";
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+    Record *Reg = Regs[i]->TheDef;
+    BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
+    uint64_t Value = 0;
+    for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
+      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(b)))
+      Value |= (uint64_t)B->getValue() << b;
+    }
+    OS << "  " << Value << ",\n";
+  }
+  OS << "};\n";       // End of HW encoding table
+
   // MCRegisterInfo initialization routine.
   OS << "static inline void Init" << TargetName
      << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
@@ -645,9 +662,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
      << RegisterClasses.size() << ", " << TargetName << "RegLists, ";
   if (SubRegIndices.size() != 0)
     OS << "(uint16_t*)" << TargetName << "SubRegTable, "
-       << SubRegIndices.size() << ");\n\n";
+       << SubRegIndices.size() << ",\n";
   else
-    OS << "NULL, 0);\n\n";
+    OS << "NULL, 0,\n";
+
+  OS << "  " << TargetName << "RegEncodingTable);\n\n";
 
   EmitRegMapping(OS, Regs, false);
 
@@ -1001,6 +1020,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
   if (SubRegIndices.size() != 0)
     OS << "extern const uint16_t *get" << TargetName
        << "SubRegTable();\n";
+  OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
 
   EmitRegMappingTables(OS, Regs, true);
 
@@ -1016,9 +1036,11 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
      << "                     ";
   if (SubRegIndices.size() != 0)
     OS << "get" << TargetName << "SubRegTable(), "
-       << SubRegIndices.size() << ");\n\n";
+       << SubRegIndices.size() << ",\n";
   else
-    OS << "NULL, 0);\n\n";
+    OS << "NULL, 0,\n";
+
+  OS << "                     " << TargetName << "RegEncodingTable);\n\n";
 
   EmitRegMapping(OS, Regs, true);
 
-------------- next part --------------
diff --git include/llvm/Support/TargetRegistry.h include/llvm/Support/TargetRegistry.h
index c9d5fc3..394c626 100644
--- include/llvm/Support/TargetRegistry.h
+++ include/llvm/Support/TargetRegistry.h
@@ -108,6 +108,7 @@ namespace llvm {
                                                   const MCRegisterInfo &MRI,
                                                   const MCSubtargetInfo &STI);
     typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
+                                                  const MCRegisterInfo &MRI,
                                                   const MCSubtargetInfo &STI,
                                                   MCContext &Ctx);
     typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
@@ -405,11 +406,12 @@ namespace llvm {
 
     /// createMCCodeEmitter - Create a target specific code emitter.
     MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
+                                       const MCRegisterInfo &MRI,
                                        const MCSubtargetInfo &STI,
                                        MCContext &Ctx) const {
       if (!MCCodeEmitterCtorFn)
         return 0;
-      return MCCodeEmitterCtorFn(II, STI, Ctx);
+      return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
     }
 
     /// createMCObjectStreamer - Create a target specific MCStreamer.
diff --git lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/LLVMTargetMachine.cpp
index a1f479a..119a150 100644
--- lib/CodeGen/LLVMTargetMachine.cpp
+++ lib/CodeGen/LLVMTargetMachine.cpp
@@ -165,6 +165,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
     Context->setAllowTemporaryLabels(false);
 
   const MCAsmInfo &MAI = *getMCAsmInfo();
+  const MCRegisterInfo &MRI = *getTarget().createMCRegInfo(getTargetTriple());
   const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
   OwningPtr<MCStreamer> AsmStreamer;
 
@@ -180,7 +181,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
     MCAsmBackend *MAB = 0;
     if (ShowMCEncoding) {
       const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
-      MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context);
+      MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI,
+                                            *Context);
       MAB = getTarget().createMCAsmBackend(getTargetTriple());
     }
 
@@ -198,8 +200,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
   case CGFT_ObjectFile: {
     // Create the code emitter for the target if it exists.  If not, .o file
     // emission fails.
-    MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI,
-                                                         *Context);
+    MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
+                                                         STI, *Context);
     MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
     if (MCE == 0 || MAB == 0)
       return true;
@@ -271,9 +273,10 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
 
   // Create the code emitter for the target if it exists.  If not, .o file
   // emission fails.
+  const MCRegisterInfo &MRI = *getTarget().createMCRegInfo(getTargetTriple());
   const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
-  MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(),STI,
-                                                       *Ctx);
+  MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
+                                                       STI, *Ctx);
   MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple());
   if (MCE == 0 || MAB == 0)
     return true;
diff --git lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 31f43fe..1964bcd 100644
--- lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -336,6 +336,7 @@ public:
 } // end anonymous namespace
 
 MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII,
+                                            const MCRegisterInfo &MRI,
                                             const MCSubtargetInfo &STI,
                                             MCContext &Ctx) {
   return new ARMMCCodeEmitter(MCII, STI, Ctx);
diff --git lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
index 5771936..510302d 100644
--- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
+++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
@@ -23,6 +23,7 @@ class MCCodeEmitter;
 class MCContext;
 class MCInstrInfo;
 class MCObjectWriter;
+class MCRegisterInfo;
 class MCSubtargetInfo;
 class StringRef;
 class Target;
@@ -41,6 +42,7 @@ namespace ARM_MC {
 }
 
 MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII,
+                                      const MCRegisterInfo &MRI,
                                       const MCSubtargetInfo &STI,
                                       MCContext &Ctx);
 
diff --git lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp
index c9b1636..bfd11a0 100644
--- lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp
+++ lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp
@@ -98,6 +98,7 @@ public:
 
 
 MCCodeEmitter *llvm::createMBlazeMCCodeEmitter(const MCInstrInfo &MCII,
+                                               const MCRegisterInfo &MRI,
                                                const MCSubtargetInfo &STI,
                                                MCContext &Ctx) {
   return new MBlazeMCCodeEmitter(MCII, STI, Ctx);
diff --git lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h
index ae82c32..7cc96c6 100644
--- lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h
+++ lib/Target/MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h
@@ -22,6 +22,7 @@ class MCContext;
 class MCCodeEmitter;
 class MCInstrInfo;
 class MCObjectWriter;
+class MCRegisterInfo;
 class MCSubtargetInfo;
 class Target;
 class StringRef;
@@ -30,6 +31,7 @@ class raw_ostream;
 extern Target TheMBlazeTarget;
 
 MCCodeEmitter *createMBlazeMCCodeEmitter(const MCInstrInfo &MCII,
+                                         const MCRegisterInfo &MRI,
                                          const MCSubtargetInfo &STI,
                                          MCContext &Ctx);
 
diff --git lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 4ed2be0..6353da3 100644
--- lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -91,6 +91,7 @@ public:
 }  // namespace
 
 MCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
+                                               const MCRegisterInfo &MRI,
                                                const MCSubtargetInfo &STI,
                                                MCContext &Ctx)
 {
@@ -98,6 +99,7 @@ MCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
 }
 
 MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
+                                               const MCRegisterInfo &MRI,
                                                const MCSubtargetInfo &STI,
                                                MCContext &Ctx)
 {
diff --git lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
index 547ccdd..bfcc2a2 100644
--- lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
+++ lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
@@ -22,6 +22,7 @@ class MCCodeEmitter;
 class MCContext;
 class MCInstrInfo;
 class MCObjectWriter;
+class MCRegisterInfo;
 class MCSubtargetInfo;
 class StringRef;
 class Target;
@@ -33,9 +34,11 @@ extern Target TheMips64Target;
 extern Target TheMips64elTarget;
 
 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
+                                         const MCRegisterInfo &MRI,
                                          const MCSubtargetInfo &STI,
                                          MCContext &Ctx);
 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
+                                         const MCRegisterInfo &MRI,
                                          const MCSubtargetInfo &STI,
                                          MCContext &Ctx);
 
diff --git lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
index 5a6827f..f652422 100644
--- lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -77,6 +77,7 @@ public:
 } // end anonymous namespace
   
 MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII,
+                                            const MCRegisterInfo &MRI,
                                             const MCSubtargetInfo &STI,
                                             MCContext &Ctx) {
   return new PPCMCCodeEmitter(MCII, STI, Ctx);
diff --git lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
index b7fa064..7162e15 100644
--- lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
+++ lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
@@ -22,6 +22,7 @@ class MCCodeEmitter;
 class MCContext;
 class MCInstrInfo;
 class MCObjectWriter;
+class MCRegisterInfo;
 class MCSubtargetInfo;
 class Target;
 class StringRef;
@@ -31,6 +32,7 @@ extern Target ThePPC32Target;
 extern Target ThePPC64Target;
   
 MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII,
+                                      const MCRegisterInfo &MRI,
                                       const MCSubtargetInfo &STI,
                                       MCContext &Ctx);
 
diff --git lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 80990e5..3b2f191 100644
--- lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -139,6 +139,7 @@ public:
 
 
 MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII,
+                                            const MCRegisterInfo &MRI,
                                             const MCSubtargetInfo &STI,
                                             MCContext &Ctx) {
   return new X86MCCodeEmitter(MCII, STI, Ctx);
diff --git lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
index 9896cbe..4650069 100644
--- lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
+++ lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
@@ -76,6 +76,7 @@ namespace X86_MC {
 }
 
 MCCodeEmitter *createX86MCCodeEmitter(const MCInstrInfo &MCII,
+                                      const MCRegisterInfo &MRI,
                                       const MCSubtargetInfo &STI,
                                       MCContext &Ctx);
 
diff --git tools/llvm-mc/llvm-mc.cpp tools/llvm-mc/llvm-mc.cpp
index 13cb517..3bceb14 100644
--- tools/llvm-mc/llvm-mc.cpp
+++ tools/llvm-mc/llvm-mc.cpp
@@ -408,7 +408,7 @@ int main(int argc, char **argv) {
     MCCodeEmitter *CE = 0;
     MCAsmBackend *MAB = 0;
     if (ShowEncoding) {
-      CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
       MAB = TheTarget->createMCAsmBackend(TripleName);
     }
     Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
@@ -421,7 +421,7 @@ int main(int argc, char **argv) {
     Str.reset(createNullStreamer(Ctx));
   } else {
     assert(FileType == OFT_ObjectFile && "Invalid file type!");
-    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
     MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName);
     Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
                                                 FOS, CE, RelaxAll,


More information about the llvm-commits mailing list