Skip to content

Commit 0242689

Browse files
committed
Revert rL342466: [llvm-exegesis] Improve Register Setup.
rL342465 is breaking the MSVC buildbots, but I need to revert this dependent revision as well. Summary: Added function to set a register to a particular value + tests. Add EFLAGS test, use new setRegTo instead of setRegToConstant. Reviewers: courbet, javed.absar Subscribers: mgorny, tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D51856 llvm-svn: 342489
1 parent 68f73c1 commit 0242689

File tree

16 files changed

+137
-187
lines changed

16 files changed

+137
-187
lines changed

llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "../Target.h"
1010
#include "../Latency.h"
1111
#include "AArch64.h"
12-
#include "AArch64RegisterInfo.h"
1312

1413
namespace exegesis {
1514

@@ -27,51 +26,33 @@ class AArch64LatencyBenchmarkRunner : public LatencyBenchmarkRunner {
2726
}
2827
};
2928

30-
namespace {
31-
32-
static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
33-
switch (RegBitWidth) {
34-
case 32:
35-
return llvm::AArch64::MOVi32imm;
36-
case 64:
37-
return llvm::AArch64::MOVi64imm;
29+
class ExegesisAArch64Target : public ExegesisTarget {
30+
std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
31+
const llvm::APInt &Value,
32+
unsigned Reg) const override {
33+
llvm_unreachable("Not yet implemented");
3834
}
39-
llvm_unreachable("Invalid Value Width");
40-
}
4135

42-
// Generates instruction to load an immediate value into a register.
43-
static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
44-
const llvm::APInt &Value) {
45-
if (Value.getBitWidth() > RegBitWidth)
46-
llvm_unreachable("Value must fit in the Register");
47-
return llvm::MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
48-
.addReg(Reg)
49-
.addImm(Value.getZExtValue());
50-
}
36+
unsigned getScratchMemoryRegister(const llvm::Triple &) const override {
37+
llvm_unreachable("Not yet implemented");
38+
}
5139

52-
} // namespace
40+
void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
41+
unsigned Offset) const override {
42+
llvm_unreachable("Not yet implemented");
43+
}
5344

54-
class ExegesisAArch64Target : public ExegesisTarget {
55-
std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
56-
unsigned Reg,
57-
const llvm::APInt &Value) const override {
58-
if (llvm::AArch64::GPR32RegClass.contains(Reg))
59-
return {loadImmediate(Reg, 32, Value)};
60-
if (llvm::AArch64::GPR64RegClass.contains(Reg))
61-
return {loadImmediate(Reg, 64, Value)};
62-
llvm::errs() << "setRegTo is not implemented, results will be unreliable\n";
63-
return {};
45+
unsigned getMaxMemoryAccessSize() const override {
46+
llvm_unreachable("Not yet implemented");
6447
}
6548

6649
bool matchesArch(llvm::Triple::ArchType Arch) const override {
6750
return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be;
6851
}
69-
7052
void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
7153
// Function return is a pseudo-instruction that needs to be expanded
7254
PM.add(llvm::createAArch64ExpandPseudoPass());
7355
}
74-
7556
std::unique_ptr<BenchmarkRunner>
7657
createLatencyBenchmarkRunner(const LLVMState &State) const override {
7758
return llvm::make_unique<AArch64LatencyBenchmarkRunner>(State);

llvm/tools/llvm-exegesis/lib/Assembler.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@ static constexpr const char ModuleID[] = "ExegesisInfoTest";
2929
static constexpr const char FunctionID[] = "foo";
3030

3131
static std::vector<llvm::MCInst>
32-
generateSnippetSetupCode(const ExegesisTarget &ET,
33-
const llvm::MCSubtargetInfo *const MSI,
34-
llvm::ArrayRef<RegisterValue> RegisterInitialValues,
35-
bool &IsSnippetSetupComplete) {
32+
generateSnippetSetupCode(const llvm::ArrayRef<unsigned> RegsToDef,
33+
const ExegesisTarget &ET,
34+
const llvm::LLVMTargetMachine &TM, bool &IsComplete) {
35+
IsComplete = true;
3636
std::vector<llvm::MCInst> Result;
37-
for (const RegisterValue &RV : RegisterInitialValues) {
38-
// Load a constant in the register.
39-
const auto SetRegisterCode = ET.setRegTo(*MSI, RV.Register, RV.Value);
40-
if (SetRegisterCode.empty())
41-
IsSnippetSetupComplete = false;
42-
Result.insert(Result.end(), SetRegisterCode.begin(), SetRegisterCode.end());
43-
}
37+
// for (const unsigned Reg : RegsToDef) {
38+
// // Load a constant in the register.
39+
// const auto Code = ET.setRegToConstant(*TM.getMCSubtargetInfo(), Reg);
40+
// if (Code.empty())
41+
// IsComplete = false;
42+
// Result.insert(Result.end(), Code.begin(), Code.end());
43+
// }
4444
return Result;
4545
}
4646

@@ -149,7 +149,7 @@ llvm::BitVector getFunctionReservedRegs(const llvm::TargetMachine &TM) {
149149
void assembleToStream(const ExegesisTarget &ET,
150150
std::unique_ptr<llvm::LLVMTargetMachine> TM,
151151
llvm::ArrayRef<unsigned> LiveIns,
152-
llvm::ArrayRef<RegisterValue> RegisterInitialValues,
152+
llvm::ArrayRef<unsigned> RegsToDef,
153153
llvm::ArrayRef<llvm::MCInst> Instructions,
154154
llvm::raw_pwrite_stream &AsmStream) {
155155
std::unique_ptr<llvm::LLVMContext> Context =
@@ -171,12 +171,13 @@ void assembleToStream(const ExegesisTarget &ET,
171171
MF.getRegInfo().addLiveIn(Reg);
172172

173173
bool IsSnippetSetupComplete = false;
174-
std::vector<llvm::MCInst> Code =
175-
generateSnippetSetupCode(ET, TM->getMCSubtargetInfo(),
176-
RegisterInitialValues, IsSnippetSetupComplete);
177-
178-
Code.insert(Code.end(), Instructions.begin(), Instructions.end());
179-
174+
std::vector<llvm::MCInst> SnippetWithSetup =
175+
generateSnippetSetupCode(RegsToDef, ET, *TM, IsSnippetSetupComplete);
176+
if (!SnippetWithSetup.empty()) {
177+
SnippetWithSetup.insert(SnippetWithSetup.end(), Instructions.begin(),
178+
Instructions.end());
179+
Instructions = SnippetWithSetup;
180+
}
180181
// If the snippet setup is not complete, we disable liveliness tracking. This
181182
// means that we won't know what values are in the registers.
182183
if (!IsSnippetSetupComplete)
@@ -187,7 +188,7 @@ void assembleToStream(const ExegesisTarget &ET,
187188
MF.getRegInfo().freezeReservedRegs(MF);
188189

189190
// Fill the MachineFunction from the instructions.
190-
fillMachineFunction(MF, LiveIns, Code);
191+
fillMachineFunction(MF, LiveIns, Instructions);
191192

192193
// We create the pass manager, run the passes to populate AsmBuffer.
193194
llvm::MCContext &MCContext = MMI->getContext();

llvm/tools/llvm-exegesis/lib/Assembler.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,14 @@ class ExegesisTarget;
3939
// convention and target machine).
4040
llvm::BitVector getFunctionReservedRegs(const llvm::TargetMachine &TM);
4141

42-
// A simple object storing the value for a particular register.
43-
struct RegisterValue {
44-
unsigned Register;
45-
llvm::APInt Value;
46-
};
47-
4842
// Creates a temporary `void foo(char*)` function containing the provided
4943
// Instructions. Runs a set of llvm Passes to provide correct prologue and
5044
// epilogue. Once the MachineFunction is ready, it is assembled for TM to
5145
// AsmStream, the temporary function is eventually discarded.
5246
void assembleToStream(const ExegesisTarget &ET,
5347
std::unique_ptr<llvm::LLVMTargetMachine> TM,
5448
llvm::ArrayRef<unsigned> LiveIns,
55-
llvm::ArrayRef<RegisterValue> RegisterInitialValues,
49+
llvm::ArrayRef<unsigned> RegsToDef,
5650
llvm::ArrayRef<llvm::MCInst> Instructions,
5751
llvm::raw_pwrite_stream &AsmStream);
5852

llvm/tools/llvm-exegesis/lib/BenchmarkCode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct BenchmarkCode {
2323

2424
// Before the code is executed some instructions are added to setup the
2525
// registers initial values.
26-
std::vector<RegisterValue> RegisterInitialValues;
26+
std::vector<unsigned> RegsToDef;
2727

2828
// We also need to provide the registers that are live on entry for the
2929
// assembler to generate proper prologue/epilogue.

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ BenchmarkRunner::writeObjectFile(const BenchmarkCode &BC,
104104
return std::move(E);
105105
llvm::raw_fd_ostream OFS(ResultFD, true /*ShouldClose*/);
106106
assembleToStream(State.getExegesisTarget(), State.createTargetMachine(),
107-
BC.LiveIns, BC.RegisterInitialValues, Code, OFS);
107+
BC.LiveIns, BC.RegsToDef, Code, OFS);
108108
return ResultPath.str();
109109
}
110110

llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,22 @@ SnippetGenerator::generateConfigurations(unsigned Opcode) const {
4949
}
5050
if (CT.ScratchSpacePointerInReg)
5151
BC.LiveIns.push_back(CT.ScratchSpacePointerInReg);
52-
BC.RegisterInitialValues = computeRegisterInitialValues(CT.Instructions);
52+
BC.RegsToDef = computeRegsToDef(CT.Instructions);
5353
Output.push_back(std::move(BC));
5454
}
5555
return Output;
5656
} else
5757
return E.takeError();
5858
}
5959

60-
std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
60+
std::vector<unsigned> SnippetGenerator::computeRegsToDef(
6161
const std::vector<InstructionBuilder> &Instructions) const {
6262
// Collect all register uses and create an assignment for each of them.
6363
// Ignore memory operands which are handled separately.
6464
// Loop invariant: DefinedRegs[i] is true iif it has been set at least once
6565
// before the current instruction.
6666
llvm::BitVector DefinedRegs = RATC.emptyRegisters();
67-
std::vector<RegisterValue> RIV;
67+
std::vector<unsigned> RegsToDef;
6868
for (const InstructionBuilder &IB : Instructions) {
6969
// Returns the register that this Operand sets or uses, or 0 if this is not
7070
// a register.
@@ -82,7 +82,7 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
8282
if (!Op.IsDef) {
8383
const unsigned Reg = GetOpReg(Op);
8484
if (Reg > 0 && !DefinedRegs.test(Reg)) {
85-
RIV.push_back(RegisterValue{Reg, llvm::APInt()});
85+
RegsToDef.push_back(Reg);
8686
DefinedRegs.set(Reg);
8787
}
8888
}
@@ -96,7 +96,7 @@ std::vector<RegisterValue> SnippetGenerator::computeRegisterInitialValues(
9696
}
9797
}
9898
}
99-
return RIV;
99+
return RegsToDef;
100100
}
101101

102102
llvm::Expected<CodeTemplate> SnippetGenerator::generateSelfAliasingCodeTemplate(

llvm/tools/llvm-exegesis/lib/SnippetGenerator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class SnippetGenerator {
4848
generateConfigurations(unsigned Opcode) const;
4949

5050
// Given a snippet, computes which registers the setup code needs to define.
51-
std::vector<RegisterValue> computeRegisterInitialValues(
52-
const std::vector<InstructionBuilder> &Snippet) const;
51+
std::vector<unsigned>
52+
computeRegsToDef(const std::vector<InstructionBuilder> &Snippet) const;
5353

5454
protected:
5555
const LLVMState &State;

llvm/tools/llvm-exegesis/lib/Target.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,21 @@ namespace {
9090
class ExegesisDefaultTarget : public ExegesisTarget {
9191
private:
9292
std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
93-
unsigned Reg,
94-
const llvm::APInt &Value) const override {
93+
const llvm::APInt &Value,
94+
unsigned Reg) const override {
95+
llvm_unreachable("Not yet implemented");
96+
}
97+
98+
unsigned getScratchMemoryRegister(const llvm::Triple &) const override {
99+
llvm_unreachable("Not yet implemented");
100+
}
101+
102+
void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
103+
unsigned Offset) const override {
104+
llvm_unreachable("Not yet implemented");
105+
}
106+
107+
unsigned getMaxMemoryAccessSize() const override {
95108
llvm_unreachable("Not yet implemented");
96109
}
97110

llvm/tools/llvm-exegesis/lib/Target.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,25 @@ class ExegesisTarget {
3636
virtual void addTargetSpecificPasses(llvm::PassManagerBase &PM) const {}
3737

3838
// Generates code to move a constant into a the given register.
39-
// Precondition: Value must fit into Reg.
40-
virtual std::vector<llvm::MCInst>
41-
setRegTo(const llvm::MCSubtargetInfo &STI, unsigned Reg,
42-
const llvm::APInt &Value) const = 0;
39+
virtual std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
40+
const llvm::APInt &Value,
41+
unsigned Reg) const = 0;
4342

4443
// Returns the register pointing to scratch memory, or 0 if this target
4544
// does not support memory operands. The benchmark function uses the
4645
// default calling convention.
47-
virtual unsigned getScratchMemoryRegister(const llvm::Triple &) const {
48-
return 0;
49-
}
46+
virtual unsigned getScratchMemoryRegister(const llvm::Triple &) const = 0;
5047

5148
// Fills memory operands with references to the address at [Reg] + Offset.
5249
virtual void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
53-
unsigned Offset) const {
54-
llvm_unreachable(
55-
"fillMemoryOperands() requires getScratchMemoryRegister() > 0");
56-
}
50+
unsigned Offset) const = 0;
5751

5852
// Returns the maximum number of bytes a load/store instruction can access at
5953
// once. This is typically the size of the largest register available on the
6054
// processor. Note that this only used as a hint to generate independant
6155
// load/stores to/from memory, so the exact returned value does not really
6256
// matter as long as it's large enough.
63-
virtual unsigned getMaxMemoryAccessSize() const { return 0; }
57+
virtual unsigned getMaxMemoryAccessSize() const = 0;
6458

6559
// Creates a snippet generator for the given mode.
6660
std::unique_ptr<SnippetGenerator>

0 commit comments

Comments
 (0)