Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 79c7f62

Browse files
committed
[Mips][llvm-exegesis] Add a Mips target
The target does just enough to be able to run llvm-exegesis in latency mode for at least some opcodes. Patch by Miloš Stojanović. Differential Revision: https://reviews.llvm.org/D68649 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374590 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f4daa70 commit 79c7f62

File tree

11 files changed

+253
-1
lines changed

11 files changed

+253
-1
lines changed

lib/Target/Mips/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ tablegen(LLVM MipsGenMCPseudoLowering.inc -gen-pseudo-lowering)
1313
tablegen(LLVM MipsGenRegisterBank.inc -gen-register-bank)
1414
tablegen(LLVM MipsGenRegisterInfo.inc -gen-register-info)
1515
tablegen(LLVM MipsGenSubtargetInfo.inc -gen-subtarget)
16+
tablegen(LLVM MipsGenExegesis.inc -gen-exegesis)
1617

1718
add_public_tablegen_target(MipsCommonTableGen)
1819

lib/Target/Mips/Mips.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,9 @@ def Mips : Target {
263263
let AssemblyParserVariants = [MipsAsmParserVariant];
264264
let AllowRegisterRenaming = 1;
265265
}
266+
267+
//===----------------------------------------------------------------------===//
268+
// Pfm Counters
269+
//===----------------------------------------------------------------------===//
270+
271+
include "MipsPfmCounters.td"

lib/Target/Mips/MipsPfmCounters.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===-- MipsPfmCounters.td - Mips Hardware Counters --------*- tablegen -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This describes the available hardware counters for Mips.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
def CpuCyclesPfmCounter : PfmCounter<"CYCLES">;
14+
15+
def DefaultPfmCounters : ProcPfmCounters {
16+
let CycleCounter = CpuCyclesPfmCounter;
17+
}
18+
def : PfmCountersDefaultBinding<DefaultPfmCounters>;

tools/llvm-exegesis/lib/Assembler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,11 @@ void assembleToStream(const ExegesisTarget &ET,
227227
ET.addTargetSpecificPasses(PM);
228228
TPC->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
229229
// Adding the following passes:
230+
// - postrapseudos: expands pseudo return instructions used on some targets.
230231
// - machineverifier: checks that the MachineFunction is well formed.
231232
// - prologepilog: saves and restore callee saved registers.
232-
for (const char *PassName : {"machineverifier", "prologepilog"})
233+
for (const char *PassName :
234+
{"postrapseudos", "machineverifier", "prologepilog"})
233235
if (addPass(PM, PassName, *TPC))
234236
report_fatal_error("Unable to add a mandatory pass");
235237
TPC->setInitialized();

tools/llvm-exegesis/lib/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ if (LLVM_TARGETS_TO_BUILD MATCHES "PowerPC")
1212
add_subdirectory(PowerPC)
1313
set(TARGETS_TO_APPEND "${TARGETS_TO_APPEND} PowerPC")
1414
endif()
15+
if (LLVM_TARGETS_TO_BUILD MATCHES "Mips")
16+
add_subdirectory(Mips)
17+
set(TARGETS_TO_APPEND "${TARGETS_TO_APPEND} Mips")
18+
endif()
1519

1620
set(LLVM_EXEGESIS_TARGETS "${LLVM_EXEGESIS_TARGETS} ${TARGETS_TO_APPEND}" PARENT_SCOPE)
1721

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
include_directories(
2+
${LLVM_MAIN_SRC_DIR}/lib/Target/Mips
3+
${LLVM_BINARY_DIR}/lib/Target/Mips
4+
)
5+
6+
add_library(LLVMExegesisMips
7+
STATIC
8+
Target.cpp
9+
)
10+
11+
llvm_update_compile_flags(LLVMExegesisMips)
12+
llvm_map_components_to_libnames(libs
13+
Mips
14+
Exegesis
15+
)
16+
17+
target_link_libraries(LLVMExegesisMips ${libs})
18+
set_target_properties(LLVMExegesisMips PROPERTIES FOLDER "Libraries")
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
;===- ./tools/llvm-exegesis/lib/Mips/LLVMBuild.txt -------------*- Conf -*--===;
2+
;
3+
; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
; See https://llvm.org/LICENSE.txt for license information.
5+
; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
;
7+
;===------------------------------------------------------------------------===;
8+
;
9+
; This is an LLVMBuild description file for the components in this subdirectory.
10+
;
11+
; For more information on the LLVMBuild system, please see:
12+
;
13+
; http://llvm.org/docs/LLVMBuild.html
14+
;
15+
;===------------------------------------------------------------------------===;
16+
17+
[component_0]
18+
type = Library
19+
name = ExegesisMips
20+
parent = Libraries
21+
required_libraries = Mips
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "../Target.h"
9+
#include "../Latency.h"
10+
#include "Mips.h"
11+
#include "MipsRegisterInfo.h"
12+
13+
namespace llvm {
14+
namespace exegesis {
15+
16+
#include "MipsGenExegesis.inc"
17+
18+
namespace {
19+
class ExegesisMipsTarget : public ExegesisTarget {
20+
public:
21+
ExegesisMipsTarget() : ExegesisTarget(MipsCpuPfmCounters) {}
22+
23+
private:
24+
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
25+
const APInt &Value) const override;
26+
bool matchesArch(Triple::ArchType Arch) const override {
27+
return Arch == Triple::mips || Arch == Triple::mipsel ||
28+
Arch == Triple::mips64 || Arch == Triple::mips64el;
29+
}
30+
};
31+
} // end anonymous namespace
32+
33+
// Generates instruction to load an immediate value into a register.
34+
static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
35+
const APInt &Value) {
36+
if (Value.getActiveBits() > 16)
37+
llvm_unreachable("Not implemented for Values wider than 16 bits");
38+
if (Value.getBitWidth() > RegBitWidth)
39+
llvm_unreachable("Value must fit in the Register");
40+
return MCInstBuilder(Mips::ORi)
41+
.addReg(Reg)
42+
.addReg(Mips::ZERO)
43+
.addImm(Value.getZExtValue());
44+
}
45+
46+
std::vector<MCInst> ExegesisMipsTarget::setRegTo(const MCSubtargetInfo &STI,
47+
unsigned Reg,
48+
const APInt &Value) const {
49+
if (Mips::GPR32RegClass.contains(Reg))
50+
return {loadImmediate(Reg, 32, Value)};
51+
if (Mips::GPR64RegClass.contains(Reg))
52+
return {loadImmediate(Reg, 64, Value)};
53+
errs() << "setRegTo is not implemented, results will be unreliable\n";
54+
return {};
55+
}
56+
57+
static ExegesisTarget *getTheExegesisMipsTarget() {
58+
static ExegesisMipsTarget Target;
59+
return &Target;
60+
}
61+
62+
void InitializeMipsExegesisTarget() {
63+
ExegesisTarget::registerTarget(getTheExegesisMipsTarget());
64+
}
65+
66+
} // namespace exegesis
67+
} // namespace llvm

unittests/tools/llvm-exegesis/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ endif()
3030
if(LLVM_TARGETS_TO_BUILD MATCHES "PowerPC")
3131
add_subdirectory(PowerPC)
3232
endif()
33+
if(LLVM_TARGETS_TO_BUILD MATCHES "Mips")
34+
add_subdirectory(Mips)
35+
endif()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
include_directories(
2+
${LLVM_MAIN_SRC_DIR}/lib/Target/Mips
3+
${LLVM_BINARY_DIR}/lib/Target/Mips
4+
${LLVM_MAIN_SRC_DIR}/tools/llvm-exegesis/lib
5+
)
6+
7+
set(LLVM_LINK_COMPONENTS
8+
MC
9+
MCParser
10+
Object
11+
Support
12+
Symbolize
13+
Mips
14+
)
15+
16+
add_llvm_unittest(LLVMExegesisMipsTests
17+
TargetTest.cpp
18+
)
19+
target_link_libraries(LLVMExegesisMipsTests PRIVATE
20+
LLVMExegesis
21+
LLVMExegesisMips)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//===-- TargetTest.cpp ------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "Target.h"
10+
11+
#include <cassert>
12+
#include <memory>
13+
14+
#include "MCTargetDesc/MipsMCTargetDesc.h"
15+
#include "llvm/Support/TargetRegistry.h"
16+
#include "llvm/Support/TargetSelect.h"
17+
#include "gmock/gmock.h"
18+
#include "gtest/gtest.h"
19+
20+
namespace llvm {
21+
namespace exegesis {
22+
23+
void InitializeMipsExegesisTarget();
24+
25+
namespace {
26+
27+
using testing::AllOf;
28+
using testing::ElementsAre;
29+
using testing::Eq;
30+
using testing::Matcher;
31+
using testing::Property;
32+
33+
Matcher<MCOperand> IsImm(int64_t Value) {
34+
return AllOf(Property(&MCOperand::isImm, Eq(true)),
35+
Property(&MCOperand::getImm, Eq(Value)));
36+
}
37+
38+
Matcher<MCOperand> IsReg(unsigned Reg) {
39+
return AllOf(Property(&MCOperand::isReg, Eq(true)),
40+
Property(&MCOperand::getReg, Eq(Reg)));
41+
}
42+
43+
Matcher<MCInst> OpcodeIs(unsigned Opcode) {
44+
return Property(&MCInst::getOpcode, Eq(Opcode));
45+
}
46+
47+
Matcher<MCInst> IsLoadLowImm(int64_t Reg, int64_t Value) {
48+
return AllOf(OpcodeIs(Mips::ORi),
49+
ElementsAre(IsReg(Reg), IsReg(Mips::ZERO), IsImm(Value)));
50+
}
51+
52+
constexpr const char kTriple[] = "mips-unknown-linux";
53+
54+
class MipsTargetTest : public ::testing::Test {
55+
protected:
56+
MipsTargetTest() : State(kTriple, "mips32", "") {}
57+
58+
static void SetUpTestCase() {
59+
LLVMInitializeMipsTargetInfo();
60+
LLVMInitializeMipsTarget();
61+
LLVMInitializeMipsTargetMC();
62+
InitializeMipsExegesisTarget();
63+
}
64+
65+
std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) {
66+
return State.getExegesisTarget().setRegTo(State.getSubtargetInfo(), Reg,
67+
Value);
68+
}
69+
70+
LLVMState State;
71+
};
72+
73+
TEST_F(MipsTargetTest, SetRegToConstant) {
74+
const uint16_t Value = 0xFFFFU;
75+
const unsigned Reg = Mips::T0;
76+
EXPECT_THAT(setRegTo(Reg, APInt(16, Value)),
77+
ElementsAre(IsLoadLowImm(Reg, Value)));
78+
}
79+
80+
TEST_F(MipsTargetTest, DefaultPfmCounters) {
81+
const std::string Expected = "CYCLES";
82+
EXPECT_EQ(State.getExegesisTarget().getPfmCounters("").CycleCounter,
83+
Expected);
84+
EXPECT_EQ(
85+
State.getExegesisTarget().getPfmCounters("unknown_cpu").CycleCounter,
86+
Expected);
87+
}
88+
89+
} // namespace
90+
} // namespace exegesis
91+
} // namespace llvm

0 commit comments

Comments
 (0)