summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib')
-rw-r--r--llvm/tools/llvm-exegesis/lib/Assembler.h7
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkCode.h7
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp6
-rw-r--r--llvm/tools/llvm-exegesis/lib/X86/Target.cpp63
4 files changed, 46 insertions, 37 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.h b/llvm/tools/llvm-exegesis/lib/Assembler.h
index 76030ae8f00..f2a77168cb7 100644
--- a/llvm/tools/llvm-exegesis/lib/Assembler.h
+++ b/llvm/tools/llvm-exegesis/lib/Assembler.h
@@ -18,6 +18,7 @@
#include <memory>
+#include "BenchmarkCode.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -39,12 +40,6 @@ class ExegesisTarget;
// convention and target machine).
llvm::BitVector getFunctionReservedRegs(const llvm::TargetMachine &TM);
-// A simple object storing the value for a particular register.
-struct RegisterValue {
- unsigned Register;
- llvm::APInt Value;
-};
-
// Creates a temporary `void foo(char*)` function containing the provided
// Instructions. Runs a set of llvm Passes to provide correct prologue and
// epilogue. Once the MachineFunction is ready, it is assembled for TM to
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkCode.h b/llvm/tools/llvm-exegesis/lib/BenchmarkCode.h
index 03708683106..f0032555546 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkCode.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkCode.h
@@ -10,12 +10,19 @@
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKCODE_H
#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKCODE_H
+#include "llvm/ADT/APInt.h"
#include "llvm/MC/MCInst.h"
#include <string>
#include <vector>
namespace exegesis {
+// A simple object storing the value for a particular register.
+struct RegisterValue {
+ unsigned Register;
+ llvm::APInt Value;
+};
+
// A collection of instructions that are to be assembled, executed and measured.
struct BenchmarkCode {
// The sequence of instructions that are to be repeated.
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index 6c22d1c0cec..1536e8a5624 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -31,12 +31,12 @@ BenchmarkRunner::BenchmarkRunner(const LLVMState &State,
BenchmarkRunner::~BenchmarkRunner() = default;
-// Repeat the snippet until there are at least NumInstructions in the resulting
+// Repeat the snippet until there are at least MinInstructions in the resulting
// code.
static std::vector<llvm::MCInst>
-GenerateInstructions(const BenchmarkCode &BC, const int MinInstructions) {
+GenerateInstructions(const BenchmarkCode &BC, const size_t MinInstructions) {
std::vector<llvm::MCInst> Code = BC.Instructions;
- for (int I = 0; I < MinInstructions; ++I)
+ for (int I = 0; Code.size() < MinInstructions; ++I)
Code.push_back(BC.Instructions[I % BC.Instructions.size()]);
return Code;
}
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 2d8f9582d43..6a63e24168c 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -170,40 +170,23 @@ static llvm::MCInst releaseStackSpace(unsigned Bytes) {
// 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 @@ struct ConstantInliner {
.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 @@ private:
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;
};
OpenPOWER on IntegriCloud