Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[LoongArch] Use tablegen size for getInstSizeInBytes
Correct the pseudo atomic instruction size for branch relaxation and branch folding passes. Inspired by D118175, D118009 and D117970. Depends on D138481 Reviewed By: SixWeining, gonglingqin, xen0n Differential Revision: https://reviews.llvm.org/D138469
- Loading branch information
1 parent
f64d4a2
commit d62480c
Showing
4 changed files
with
175 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
include_directories( | ||
${LLVM_MAIN_SRC_DIR}/lib/Target/LoongArch | ||
${LLVM_BINARY_DIR}/lib/Target/LoongArch | ||
) | ||
|
||
set(LLVM_LINK_COMPONENTS | ||
AsmParser | ||
CodeGen | ||
Core | ||
GlobalISel | ||
LoongArchCodeGen | ||
LoongArchDesc | ||
LoongArchInfo | ||
MC | ||
MIRParser | ||
SelectionDAG | ||
Support | ||
Target | ||
) | ||
|
||
add_llvm_target_unittest(LoongArchTests | ||
InstSizes.cpp | ||
) | ||
|
||
set_property(TARGET LoongArchTests PROPERTY FOLDER "Tests/UnitTests/TargetTests") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#include "LoongArchSubtarget.h" | ||
#include "LoongArchTargetMachine.h" | ||
#include "llvm/CodeGen/MIRParser/MIRParser.h" | ||
#include "llvm/CodeGen/MachineModuleInfo.h" | ||
#include "llvm/MC/TargetRegistry.h" | ||
#include "llvm/Support/MemoryBuffer.h" | ||
#include "llvm/Support/TargetSelect.h" | ||
|
||
#include "gtest/gtest.h" | ||
|
||
using namespace llvm; | ||
|
||
namespace { | ||
std::unique_ptr<LLVMTargetMachine> createTargetMachine() { | ||
auto TT(Triple::normalize("loongarch64--")); | ||
std::string CPU("generic-la64"); | ||
std::string FS("+64bit"); | ||
|
||
LLVMInitializeLoongArchTargetInfo(); | ||
LLVMInitializeLoongArchTarget(); | ||
LLVMInitializeLoongArchTargetMC(); | ||
|
||
std::string Error; | ||
const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); | ||
|
||
return std::unique_ptr<LLVMTargetMachine>( | ||
static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine( | ||
TT, CPU, FS, TargetOptions(), None, None, CodeGenOpt::Default))); | ||
} | ||
|
||
std::unique_ptr<LoongArchInstrInfo> createInstrInfo(TargetMachine *TM) { | ||
LoongArchSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), | ||
std::string(TM->getTargetCPU()), | ||
std::string(TM->getTargetFeatureString()), "lp64d", | ||
*TM); | ||
return std::make_unique<LoongArchInstrInfo>(ST); | ||
} | ||
|
||
/// The \p InputIRSnippet is only needed for things that can't be expressed in | ||
/// the \p InputMIRSnippet (global variables etc) | ||
/// Inspired by AArch64 | ||
void runChecks( | ||
LLVMTargetMachine *TM, LoongArchInstrInfo *II, | ||
const StringRef InputIRSnippet, const StringRef InputMIRSnippet, | ||
std::function<void(LoongArchInstrInfo &, MachineFunction &)> Checks) { | ||
LLVMContext Context; | ||
|
||
auto MIRString = "--- |\n" | ||
" declare void @sizes()\n" + | ||
InputIRSnippet.str() + | ||
"...\n" | ||
"---\n" | ||
"name: sizes\n" | ||
"jumpTable:\n" | ||
" kind: block-address\n" | ||
" entries:\n" | ||
" - id: 0\n" | ||
" blocks: [ '%bb.0' ]\n" | ||
"body: |\n" | ||
" bb.0:\n" + | ||
InputMIRSnippet.str(); | ||
|
||
std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString); | ||
std::unique_ptr<MIRParser> MParser = | ||
createMIRParser(std::move(MBuffer), Context); | ||
ASSERT_TRUE(MParser); | ||
|
||
std::unique_ptr<Module> M = MParser->parseIRModule(); | ||
ASSERT_TRUE(M); | ||
|
||
M->setTargetTriple(TM->getTargetTriple().getTriple()); | ||
M->setDataLayout(TM->createDataLayout()); | ||
|
||
MachineModuleInfo MMI(TM); | ||
bool Res = MParser->parseMachineFunctions(*M, MMI); | ||
ASSERT_FALSE(Res); | ||
|
||
auto F = M->getFunction("sizes"); | ||
ASSERT_TRUE(F != nullptr); | ||
auto &MF = MMI.getOrCreateMachineFunction(*F); | ||
|
||
Checks(*II, MF); | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
TEST(InstSizes, INLINEASM_BR) { | ||
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine(); | ||
std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get()); | ||
|
||
runChecks(TM.get(), II.get(), "", | ||
// clang-format off | ||
" INLINEASM_BR &nop, 1 /* sideeffect attdialect */, 13 /* imm */, %jump-table.0\n", | ||
// clang-format on | ||
[](LoongArchInstrInfo &II, MachineFunction &MF) { | ||
auto I = MF.begin()->begin(); | ||
EXPECT_EQ(4u, II.getInstSizeInBytes(*I)); | ||
}); | ||
} | ||
|
||
TEST(InstSizes, SPACE) { | ||
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine(); | ||
std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get()); | ||
|
||
runChecks(TM.get(), II.get(), "", " INLINEASM &\".space 1024\", 1\n", | ||
[](LoongArchInstrInfo &II, MachineFunction &MF) { | ||
auto I = MF.begin()->begin(); | ||
EXPECT_EQ(1024u, II.getInstSizeInBytes(*I)); | ||
}); | ||
} | ||
|
||
TEST(InstSizes, AtomicPseudo) { | ||
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine(); | ||
std::unique_ptr<LoongArchInstrInfo> II = createInstrInfo(TM.get()); | ||
|
||
runChecks( | ||
TM.get(), II.get(), "", | ||
// clang-format off | ||
" dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoMaskedAtomicLoadAdd32 renamable $r7, renamable $r6, renamable $r8, 4\n" | ||
" dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoAtomicLoadAdd32 renamable $r7, renamable $r6\n" | ||
" dead early-clobber renamable $r5, dead early-clobber renamable $r9, dead early-clobber renamable $r10 = PseudoMaskedAtomicLoadUMax32 renamable $r7, renamable $r6, renamable $r8, 4\n" | ||
" early-clobber renamable $r9, dead early-clobber renamable $r10, dead early-clobber renamable $r11 = PseudoMaskedAtomicLoadMax32 killed renamable $r6, killed renamable $r5, killed renamable $r7, killed renamable $r8, 4\n" | ||
" dead early-clobber renamable $r5, dead early-clobber renamable $r9 = PseudoCmpXchg32 renamable $r7, renamable $r4, renamable $r6\n" | ||
" dead early-clobber renamable $r5, dead early-clobber renamable $r9 = PseudoMaskedCmpXchg32 killed renamable $r7, killed renamable $r4, killed renamable $r6, killed renamable $r8, 4\n", | ||
// clang-format on | ||
[](LoongArchInstrInfo &II, MachineFunction &MF) { | ||
auto I = MF.begin()->begin(); | ||
EXPECT_EQ(36u, II.getInstSizeInBytes(*I)); | ||
++I; | ||
EXPECT_EQ(24u, II.getInstSizeInBytes(*I)); | ||
++I; | ||
EXPECT_EQ(48u, II.getInstSizeInBytes(*I)); | ||
++I; | ||
EXPECT_EQ(56u, II.getInstSizeInBytes(*I)); | ||
++I; | ||
EXPECT_EQ(36u, II.getInstSizeInBytes(*I)); | ||
++I; | ||
EXPECT_EQ(44u, II.getInstSizeInBytes(*I)); | ||
}); | ||
} |