Home | History | Annotate | Download | only in AArch64
      1 #include "AArch64Subtarget.h"
      2 #include "AArch64TargetMachine.h"
      3 #include "llvm/CodeGen/MIRParser/MIRParser.h"
      4 #include "llvm/CodeGen/MachineModuleInfo.h"
      5 #include "llvm/Support/TargetRegistry.h"
      6 #include "llvm/Support/TargetSelect.h"
      7 
      8 #include "gtest/gtest.h"
      9 
     10 using namespace llvm;
     11 
     12 namespace {
     13 std::unique_ptr<TargetMachine> createTargetMachine() {
     14   auto TT(Triple::normalize("aarch64--"));
     15   std::string CPU("generic");
     16   std::string FS("");
     17 
     18   LLVMInitializeAArch64TargetInfo();
     19   LLVMInitializeAArch64Target();
     20   LLVMInitializeAArch64TargetMC();
     21 
     22   std::string Error;
     23   const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
     24 
     25   return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
     26       TT, CPU, FS, TargetOptions(), None, None, CodeGenOpt::Default));
     27 }
     28 
     29 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
     30   AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
     31                       TM->getTargetFeatureString(), *TM, /* isLittle */ false);
     32   return llvm::make_unique<AArch64InstrInfo>(ST);
     33 }
     34 
     35 /// The \p InputIRSnippet is only needed for things that can't be expressed in
     36 /// the \p InputMIRSnippet (global variables etc)
     37 /// TODO: Some of this might be useful for other architectures as well - extract
     38 ///       the platform-independent parts somewhere they can be reused.
     39 void runChecks(
     40     TargetMachine *TM, AArch64InstrInfo *II, const StringRef InputIRSnippet,
     41     const StringRef InputMIRSnippet,
     42     std::function<void(AArch64InstrInfo &, MachineFunction &)> Checks) {
     43   LLVMContext Context;
     44 
     45   auto MIRString =
     46     "--- |\n"
     47     "  declare void @sizes()\n"
     48     + InputIRSnippet.str() +
     49     "...\n"
     50     "---\n"
     51     "name: sizes\n"
     52     "body: |\n"
     53     "  bb.0:\n"
     54     + InputMIRSnippet.str();
     55 
     56   std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);
     57   std::unique_ptr<MIRParser> MParser =
     58       createMIRParser(std::move(MBuffer), Context);
     59   ASSERT_TRUE(MParser);
     60 
     61   std::unique_ptr<Module> M = MParser->parseIRModule();
     62   ASSERT_TRUE(M);
     63 
     64   M->setTargetTriple(TM->getTargetTriple().getTriple());
     65   M->setDataLayout(TM->createDataLayout());
     66 
     67   MachineModuleInfo MMI(TM);
     68   bool Res = MParser->parseMachineFunctions(*M, MMI);
     69   ASSERT_FALSE(Res);
     70 
     71   auto F = M->getFunction("sizes");
     72   ASSERT_TRUE(F != nullptr);
     73   auto &MF = MMI.getOrCreateMachineFunction(*F);
     74 
     75   Checks(*II, MF);
     76 }
     77 
     78 } // anonymous namespace
     79 
     80 TEST(InstSizes, STACKMAP) {
     81   std::unique_ptr<TargetMachine> TM = createTargetMachine();
     82   ASSERT_TRUE(TM);
     83   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
     84 
     85   runChecks(TM.get(), II.get(), "", "    STACKMAP 0, 16\n"
     86                                     "    STACKMAP 1, 32\n",
     87             [](AArch64InstrInfo &II, MachineFunction &MF) {
     88               auto I = MF.begin()->begin();
     89               EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
     90               ++I;
     91               EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
     92             });
     93 }
     94 
     95 TEST(InstSizes, PATCHPOINT) {
     96   std::unique_ptr<TargetMachine> TM = createTargetMachine();
     97   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
     98 
     99   runChecks(TM.get(), II.get(), "",
    100             "    PATCHPOINT 0, 16, 0, 0, 0, csr_aarch64_aapcs\n"
    101             "    PATCHPOINT 1, 32, 0, 0, 0, csr_aarch64_aapcs\n",
    102             [](AArch64InstrInfo &II, MachineFunction &MF) {
    103               auto I = MF.begin()->begin();
    104               EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
    105               ++I;
    106               EXPECT_EQ(32u, II.getInstSizeInBytes(*I));
    107             });
    108 }
    109 
    110 TEST(InstSizes, TLSDESC_CALLSEQ) {
    111   std::unique_ptr<TargetMachine> TM = createTargetMachine();
    112   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
    113 
    114   runChecks(
    115       TM.get(), II.get(),
    116       "  @ThreadLocalGlobal = external thread_local global i32, align 8\n",
    117       "    TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal\n",
    118       [](AArch64InstrInfo &II, MachineFunction &MF) {
    119         auto I = MF.begin()->begin();
    120         EXPECT_EQ(16u, II.getInstSizeInBytes(*I));
    121       });
    122 }
    123