[llvm-exegesis] Allow benchmarking arbitrary code snippets.

Summary:

This is a step towards fixing PR38048.

Note that right now the measurements are given per instruction. We'll
need to give measurements a per code snippet and update the analysis (PR38731).

Reviewers: gchatelet

Subscribers: tschuett, llvm-commits

Differential Revision: https://reviews.llvm.org/D52041

llvm-svn: 342947
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 2d8f958..6a63e24 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -170,40 +170,23 @@
 // Reserves some space on the stack, fills it with the content of the provided
 // constant and provide methods to load the stack value into a register.
 struct ConstantInliner {
-  explicit ConstantInliner(const llvm::APInt &Constant)
-      : StackSize(Constant.getBitWidth() / 8) {
-    assert(Constant.getBitWidth() % 8 == 0 && "Must be a multiple of 8");
-    add(allocateStackSpace(StackSize));
-    size_t ByteOffset = 0;
-    for (; StackSize - ByteOffset >= 4; ByteOffset += 4)
-      add(fillStackSpace(
-          llvm::X86::MOV32mi, ByteOffset,
-          Constant.extractBits(32, ByteOffset * 8).getZExtValue()));
-    if (StackSize - ByteOffset >= 2) {
-      add(fillStackSpace(
-          llvm::X86::MOV16mi, ByteOffset,
-          Constant.extractBits(16, ByteOffset * 8).getZExtValue()));
-      ByteOffset += 2;
-    }
-    if (StackSize - ByteOffset >= 1)
-      add(fillStackSpace(
-          llvm::X86::MOV8mi, ByteOffset,
-          Constant.extractBits(8, ByteOffset * 8).getZExtValue()));
-  }
+  explicit ConstantInliner(const llvm::APInt &Constant) : Constant_(Constant) {}
 
   std::vector<llvm::MCInst> loadAndFinalize(unsigned Reg, unsigned RegBitWidth,
                                             unsigned Opcode) {
-    assert(StackSize * 8 == RegBitWidth &&
-           "Value does not have the correct size");
+    assert((RegBitWidth & 7) == 0 &&
+           "RegBitWidth must be a multiple of 8 bits");
+    initStack(RegBitWidth / 8);
     add(loadToReg(Reg, Opcode));
-    add(releaseStackSpace(StackSize));
+    add(releaseStackSpace(RegBitWidth / 8));
     return std::move(Instructions);
   }
 
   std::vector<llvm::MCInst>
   loadX87AndFinalize(unsigned Reg, unsigned RegBitWidth, unsigned Opcode) {
-    assert(StackSize * 8 == RegBitWidth &&
-           "Value does not have the correct size");
+    assert((RegBitWidth & 7) == 0 &&
+           "RegBitWidth must be a multiple of 8 bits");
+    initStack(RegBitWidth / 8);
     add(llvm::MCInstBuilder(Opcode)
             .addReg(llvm::X86::RSP) // BaseReg
             .addImm(1)              // ScaleAmt
@@ -212,12 +195,12 @@
             .addReg(0));            // Segment
     if (Reg != llvm::X86::ST0)
       add(llvm::MCInstBuilder(llvm::X86::ST_Frr).addReg(Reg));
-    add(releaseStackSpace(StackSize));
+    add(releaseStackSpace(RegBitWidth / 8));
     return std::move(Instructions);
   }
 
   std::vector<llvm::MCInst> popFlagAndFinalize() {
-    assert(StackSize * 8 == 64 && "Value does not have the correct size");
+    initStack(8);
     add(llvm::MCInstBuilder(llvm::X86::POPF64));
     return std::move(Instructions);
   }
@@ -228,7 +211,31 @@
     return *this;
   }
 
-  const size_t StackSize;
+  void initStack(unsigned Bytes) {
+    assert(Constant_.getBitWidth() <= Bytes * 8 &&
+           "Value does not have the correct size");
+    const llvm::APInt WideConstant = Constant_.getBitWidth() < Bytes * 8
+                                         ? Constant_.sext(Bytes * 8)
+                                         : Constant_;
+    add(allocateStackSpace(Bytes));
+    size_t ByteOffset = 0;
+    for (; Bytes - ByteOffset >= 4; ByteOffset += 4)
+      add(fillStackSpace(
+          llvm::X86::MOV32mi, ByteOffset,
+          WideConstant.extractBits(32, ByteOffset * 8).getZExtValue()));
+    if (Bytes - ByteOffset >= 2) {
+      add(fillStackSpace(
+          llvm::X86::MOV16mi, ByteOffset,
+          WideConstant.extractBits(16, ByteOffset * 8).getZExtValue()));
+      ByteOffset += 2;
+    }
+    if (Bytes - ByteOffset >= 1)
+      add(fillStackSpace(
+          llvm::X86::MOV8mi, ByteOffset,
+          WideConstant.extractBits(8, ByteOffset * 8).getZExtValue()));
+  }
+
+  llvm::APInt Constant_;
   std::vector<llvm::MCInst> Instructions;
 };