diff options
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Assembler.h | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/BenchmarkCode.h | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 63 |
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; }; |