[llvm] r342464 - Improve Register Setup
Guillaume Chatelet via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 18 04:26:27 PDT 2018
Author: gchatelet
Date: Tue Sep 18 04:26:27 2018
New Revision: 342464
URL: http://llvm.org/viewvc/llvm-project?rev=342464&view=rev
Log:
Improve Register Setup
Modified:
llvm/trunk/tools/llvm-exegesis/lib/AArch64/Target.cpp
llvm/trunk/tools/llvm-exegesis/lib/Target.cpp
llvm/trunk/tools/llvm-exegesis/lib/Target.h
llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
llvm/trunk/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
Modified: llvm/trunk/tools/llvm-exegesis/lib/AArch64/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/AArch64/Target.cpp?rev=342464&r1=342463&r2=342464&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/AArch64/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/AArch64/Target.cpp Tue Sep 18 04:26:27 2018
@@ -27,6 +27,30 @@ private:
};
class ExegesisAArch64Target : public ExegesisTarget {
+ std::vector<llvm::MCInst> setRegToConstant(const llvm::MCSubtargetInfo &STI,
+ unsigned Reg) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
+ const llvm::APInt &Value,
+ unsigned Reg) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ unsigned getScratchMemoryRegister(const llvm::Triple &) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
+ unsigned Offset) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ unsigned getMaxMemoryAccessSize() const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
bool matchesArch(llvm::Triple::ArchType Arch) const override {
return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be;
}
Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.cpp?rev=342464&r1=342463&r2=342464&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.cpp Tue Sep 18 04:26:27 2018
@@ -89,6 +89,30 @@ namespace {
// Default implementation.
class ExegesisDefaultTarget : public ExegesisTarget {
private:
+ std::vector<llvm::MCInst> setRegToConstant(const llvm::MCSubtargetInfo &STI,
+ unsigned Reg) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
+ const llvm::APInt &Value,
+ unsigned Reg) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ unsigned getScratchMemoryRegister(const llvm::Triple &) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
+ unsigned Offset) const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
+ unsigned getMaxMemoryAccessSize() const override {
+ llvm_unreachable("Not yet implemented");
+ }
+
bool matchesArch(llvm::Triple::ArchType Arch) const override {
llvm_unreachable("never called");
return false;
Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.h?rev=342464&r1=342463&r2=342464&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.h Tue Sep 18 04:26:27 2018
@@ -37,30 +37,28 @@ public:
// Generates code to move a constant into a the given register.
virtual std::vector<llvm::MCInst>
- setRegToConstant(const llvm::MCSubtargetInfo &STI, unsigned Reg) const {
- return {};
- }
-
- // Returns the register pointing to scratch memory, or 0 if this target does
- // not support memory operands. The benchmark function uses the default
- // calling convention.
- virtual unsigned getScratchMemoryRegister(const llvm::Triple &) const {
- return 0;
- }
+ setRegToConstant(const llvm::MCSubtargetInfo &STI, unsigned Reg) const = 0;
+
+ // Generates code to move a constant into a the given register.
+ virtual std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
+ const llvm::APInt &Value,
+ unsigned Reg) const = 0;
+
+ // Returns the register pointing to scratch memory, or 0 if this target
+ // does not support memory operands. The benchmark function uses the
+ // default calling convention.
+ virtual unsigned getScratchMemoryRegister(const llvm::Triple &) const = 0;
// Fills memory operands with references to the address at [Reg] + Offset.
virtual void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
- unsigned Offset) const {
- llvm_unreachable(
- "fillMemoryOperands() requires getScratchMemoryRegister() > 0");
- }
+ unsigned Offset) const = 0;
// Returns the maximum number of bytes a load/store instruction can access at
// once. This is typically the size of the largest register available on the
// processor. Note that this only used as a hint to generate independant
// load/stores to/from memory, so the exact returned value does not really
// matter as long as it's large enough.
- virtual unsigned getMaxMemoryAccessSize() const { return 0; }
+ virtual unsigned getMaxMemoryAccessSize() const = 0;
// Creates a snippet generator for the given mode.
std::unique_ptr<SnippetGenerator>
Modified: llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp?rev=342464&r1=342463&r2=342464&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp Tue Sep 18 04:26:27 2018
@@ -101,6 +101,105 @@ protected:
}
};
+static unsigned GetLoadImmediateOpcode(const llvm::APInt &Value) {
+ switch (Value.getBitWidth()) {
+ case 8:
+ return llvm::X86::MOV8ri;
+ case 16:
+ return llvm::X86::MOV16ri;
+ case 32:
+ return llvm::X86::MOV32ri;
+ case 64:
+ return llvm::X86::MOV64ri;
+ }
+ llvm_unreachable("Invalid Value Width");
+}
+
+static llvm::MCInst loadImmediate(unsigned Reg, const llvm::APInt &Value) {
+ return llvm::MCInstBuilder(GetLoadImmediateOpcode(Value))
+ .addReg(Reg)
+ .addImm(Value.getZExtValue());
+}
+
+// Allocates scratch memory on the stack.
+static llvm::MCInst allocateStackSpace(unsigned Bytes) {
+ return llvm::MCInstBuilder(llvm::X86::SUB64ri8)
+ .addReg(llvm::X86::RSP)
+ .addReg(llvm::X86::RSP)
+ .addImm(Bytes);
+}
+
+// Fills scratch memory at offset `OffsetBytes` with value `Imm`.
+static llvm::MCInst fillStackSpace(unsigned MovOpcode, unsigned OffsetBytes,
+ uint64_t Imm) {
+ return llvm::MCInstBuilder(MovOpcode)
+ // Address = ESP
+ .addReg(llvm::X86::RSP) // BaseReg
+ .addImm(1) // ScaleAmt
+ .addReg(0) // IndexReg
+ .addImm(OffsetBytes) // Disp
+ .addReg(0) // Segment
+ // Immediate.
+ .addImm(Imm);
+}
+
+// Loads scratch memory into register `Reg` using opcode `RMOpcode`.
+static llvm::MCInst loadToReg(unsigned Reg, unsigned RMOpcode) {
+ return llvm::MCInstBuilder(RMOpcode)
+ .addReg(Reg)
+ // Address = ESP
+ .addReg(llvm::X86::RSP) // BaseReg
+ .addImm(1) // ScaleAmt
+ .addReg(0) // IndexReg
+ .addImm(0) // Disp
+ .addReg(0); // Segment
+}
+
+// Releases scratch memory.
+static llvm::MCInst releaseStackSpace(unsigned Bytes) {
+ return llvm::MCInstBuilder(llvm::X86::ADD64ri8)
+ .addReg(llvm::X86::RSP)
+ .addReg(llvm::X86::RSP)
+ .addImm(Bytes);
+}
+
+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()));
+ }
+
+ ConstantInliner &Add(const llvm::MCInst &Inst) {
+ Instructions.push_back(Inst);
+ return *this;
+ }
+
+ std::vector<llvm::MCInst> finalize() {
+ Add(releaseStackSpace(StackSize));
+ return std::move(Instructions);
+ }
+
+private:
+ const size_t StackSize;
+ std::vector<llvm::MCInst> Instructions;
+};
+
class ExegesisX86Target : public ExegesisTarget {
void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
// Lowers FP pseudo-instructions, e.g. ABS_Fp32 -> ABS_F.
@@ -192,7 +291,21 @@ class ExegesisX86Target : public Exegesi
Result.push_back(llvm::MCInstBuilder(llvm::X86::POPF64)); // Also pops.
return Result;
}
- return {};
+ llvm_unreachable("Not yet implemented");
+ }
+
+ std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
+ const llvm::APInt &Value,
+ unsigned Reg) const override {
+ if (llvm::X86::GR8RegClass.contains(Reg) ||
+ llvm::X86::GR16RegClass.contains(Reg) ||
+ llvm::X86::GR32RegClass.contains(Reg) ||
+ llvm::X86::GR64RegClass.contains(Reg))
+ return {loadImmediate(Reg, Value)};
+ ConstantInliner CI(Value);
+ if (llvm::X86::VR64RegClass.contains(Reg))
+ return CI.Add(loadToReg(Reg, llvm::X86::MMX_MOVQ64rm)).finalize();
+ llvm_unreachable("Not yet implemented");
}
std::unique_ptr<SnippetGenerator>
@@ -233,48 +346,6 @@ private:
Result.push_back(releaseStackSpace(RegSizeBytes));
return Result;
}
-
- // Allocates scratch memory on the stack.
- static llvm::MCInst allocateStackSpace(unsigned Bytes) {
- return llvm::MCInstBuilder(llvm::X86::SUB64ri8)
- .addReg(llvm::X86::RSP)
- .addReg(llvm::X86::RSP)
- .addImm(Bytes);
- }
-
- // Fills scratch memory at offset `OffsetBytes` with value `Imm`.
- static llvm::MCInst fillStackSpace(unsigned MovOpcode, unsigned OffsetBytes,
- uint64_t Imm) {
- return llvm::MCInstBuilder(MovOpcode)
- // Address = ESP
- .addReg(llvm::X86::RSP) // BaseReg
- .addImm(1) // ScaleAmt
- .addReg(0) // IndexReg
- .addImm(OffsetBytes) // Disp
- .addReg(0) // Segment
- // Immediate.
- .addImm(Imm);
- }
-
- // Loads scratch memory into register `Reg` using opcode `RMOpcode`.
- static llvm::MCInst loadToReg(unsigned Reg, unsigned RMOpcode) {
- return llvm::MCInstBuilder(RMOpcode)
- .addReg(Reg)
- // Address = ESP
- .addReg(llvm::X86::RSP) // BaseReg
- .addImm(1) // ScaleAmt
- .addReg(0) // IndexReg
- .addImm(0) // Disp
- .addReg(0); // Segment
- }
-
- // Releases scratch memory.
- static llvm::MCInst releaseStackSpace(unsigned Bytes) {
- return llvm::MCInstBuilder(llvm::X86::ADD64ri8)
- .addReg(llvm::X86::RSP)
- .addReg(llvm::X86::RSP)
- .addImm(Bytes);
- }
};
} // namespace
Modified: llvm/trunk/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp?rev=342464&r1=342463&r2=342464&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp Tue Sep 18 04:26:27 2018
@@ -41,13 +41,5 @@ protected:
const ExegesisTarget *const ExegesisTarget_;
};
-TEST_F(AArch64TargetTest, SetRegToConstant) {
- const std::unique_ptr<llvm::MCSubtargetInfo> STI(
- Target_->createMCSubtargetInfo(kTriple, "generic", ""));
- // The AArch64 target currently doesn't know how to set register values
- const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::AArch64::X0);
- EXPECT_THAT(Insts, SizeIs(0));
-}
-
} // namespace
} // namespace exegesis
Modified: llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp?rev=342464&r1=342463&r2=342464&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp Tue Sep 18 04:26:27 2018
@@ -9,16 +9,47 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "llvm/MC/MCInstPrinter.h"
+
+namespace llvm {
+
+bool operator==(const llvm::MCOperand &a, const llvm::MCOperand &b) {
+ if (a.isImm() && b.isImm())
+ return a.getImm() == b.getImm();
+ if (a.isReg() && b.isReg())
+ return a.getReg() == b.getReg();
+ return false;
+}
+
+bool operator==(const llvm::MCInst &a, const llvm::MCInst &b) {
+ if (a.getOpcode() != b.getOpcode())
+ return false;
+ if (a.getNumOperands() != b.getNumOperands())
+ return false;
+ for (unsigned I = 0; I < a.getNumOperands(); ++I) {
+ if (!(a.getOperand(I) == b.getOperand(I)))
+ return false;
+ }
+ return true;
+}
+
+} // namespace llvm
+
namespace exegesis {
void InitializeX86ExegesisTarget();
namespace {
+using testing::ElementsAre;
using testing::Gt;
using testing::NotNull;
using testing::SizeIs;
+using llvm::APInt;
+using llvm::MCInst;
+using llvm::MCInstBuilder;
+
constexpr const char kTriple[] = "x86_64-unknown-linux";
class X86TargetTest : public ::testing::Test {
@@ -166,5 +197,45 @@ TEST_F(X86TargetTest, SetRegToConstantZM
EXPECT_EQ(Insts[18].getOpcode(), llvm::X86::ADD64ri8);
}
+TEST_F(X86TargetTest, SetToAPInt) {
+ const std::unique_ptr<llvm::MCSubtargetInfo> STI(
+ Target_->createMCSubtargetInfo(kTriple, "core2", ""));
+ // EXPECT_THAT(ExegesisTarget_->setRegTo(*STI, APInt(8, 0xFFU),
+ // llvm::X86::AL),
+ // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV8ri)
+ // .addReg(llvm::X86::AL)
+ // .addImm(0xFFU)));
+ // EXPECT_THAT(
+ // ExegesisTarget_->setRegTo(*STI, APInt(16, 0xFFFFU), llvm::X86::BX),
+ // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV16ri)
+ // .addReg(llvm::X86::BX)
+ // .addImm(0xFFFFU)));
+ // EXPECT_THAT(
+ // ExegesisTarget_->setRegTo(*STI, APInt(32, 0x7FFFFU), llvm::X86::ECX),
+ // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV32ri)
+ // .addReg(llvm::X86::ECX)
+ // .addImm(0x7FFFFU)));
+ // EXPECT_THAT(ExegesisTarget_->setRegTo(*STI, APInt(64,
+ // 0x7FFFFFFFFFFFFFFFULL),
+ // llvm::X86::RDX),
+ // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV64ri)
+ // .addReg(llvm::X86::RDX)
+ // .addImm(0x7FFFFFFFFFFFFFFFULL)));
+
+ const std::unique_ptr<llvm::MCRegisterInfo> MRI(
+ Target_->createMCRegInfo(kTriple));
+ const std::unique_ptr<llvm::MCAsmInfo> MAI(
+ Target_->createMCAsmInfo(*MRI, kTriple));
+ const std::unique_ptr<llvm::MCInstrInfo> MII(Target_->createMCInstrInfo());
+ const std::unique_ptr<llvm::MCInstPrinter> MIP(
+ Target_->createMCInstPrinter(llvm::Triple(kTriple), 1, *MAI, *MII, *MRI));
+
+ for (const auto M : ExegesisTarget_->setRegTo(
+ *STI, APInt(80, "ABCD1234123456785678", 16), llvm::X86::MM0)) {
+ MIP->printInst(&M, llvm::errs(), "", *STI);
+ llvm::errs() << "\n";
+ }
+}
+
} // namespace
} // namespace exegesis
More information about the llvm-commits
mailing list