1 #include "RegisterAliasing.h" 2 3 #include <cassert> 4 #include <memory> 5 6 #include "X86InstrInfo.h" 7 #include "llvm/Support/TargetRegistry.h" 8 #include "llvm/Support/TargetSelect.h" 9 #include "gmock/gmock.h" 10 #include "gtest/gtest.h" 11 12 namespace llvm { 13 namespace exegesis { 14 namespace { 15 16 class RegisterAliasingTest : public ::testing::Test { 17 protected: 18 RegisterAliasingTest() { 19 const std::string TT = "x86_64-unknown-linux"; 20 std::string error; 21 const llvm::Target *const TheTarget = 22 llvm::TargetRegistry::lookupTarget(TT, error); 23 if (!TheTarget) { 24 llvm::errs() << error << "\n"; 25 return; 26 } 27 MCRegInfo.reset(TheTarget->createMCRegInfo(TT)); 28 } 29 30 static void SetUpTestCase() { 31 LLVMInitializeX86TargetInfo(); 32 LLVMInitializeX86Target(); 33 LLVMInitializeX86TargetMC(); 34 } 35 36 const llvm::MCRegisterInfo &getMCRegInfo() { 37 assert(MCRegInfo); 38 return *MCRegInfo; 39 } 40 41 private: 42 std::unique_ptr<const llvm::MCRegisterInfo> MCRegInfo; 43 }; 44 45 TEST_F(RegisterAliasingTest, TrackSimpleRegister) { 46 const auto &RegInfo = getMCRegInfo(); 47 const RegisterAliasingTracker tracker(RegInfo, llvm::X86::EAX); 48 std::set<llvm::MCPhysReg> ActualAliasedRegisters; 49 for (unsigned I : tracker.aliasedBits().set_bits()) 50 ActualAliasedRegisters.insert(static_cast<llvm::MCPhysReg>(I)); 51 const std::set<llvm::MCPhysReg> ExpectedAliasedRegisters = { 52 llvm::X86::AL, llvm::X86::AH, llvm::X86::AX, 53 llvm::X86::EAX, llvm::X86::HAX, llvm::X86::RAX}; 54 ASSERT_THAT(ActualAliasedRegisters, ExpectedAliasedRegisters); 55 for (llvm::MCPhysReg aliased : ExpectedAliasedRegisters) { 56 ASSERT_THAT(tracker.getOrigin(aliased), llvm::X86::EAX); 57 } 58 } 59 60 TEST_F(RegisterAliasingTest, TrackRegisterClass) { 61 // The alias bits for GR8_ABCD_LRegClassID are the union of the alias bits for 62 // AL, BL, CL and DL. 63 const auto &RegInfo = getMCRegInfo(); 64 const llvm::BitVector NoReservedReg(RegInfo.getNumRegs()); 65 66 const RegisterAliasingTracker RegClassTracker( 67 RegInfo, NoReservedReg, 68 RegInfo.getRegClass(llvm::X86::GR8_ABCD_LRegClassID)); 69 70 llvm::BitVector sum(RegInfo.getNumRegs()); 71 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::AL).aliasedBits(); 72 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::BL).aliasedBits(); 73 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::CL).aliasedBits(); 74 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::DL).aliasedBits(); 75 76 ASSERT_THAT(RegClassTracker.aliasedBits(), sum); 77 } 78 79 TEST_F(RegisterAliasingTest, TrackRegisterClassCache) { 80 // Fetching twice the same tracker yields the same pointers. 81 const auto &RegInfo = getMCRegInfo(); 82 const llvm::BitVector NoReservedReg(RegInfo.getNumRegs()); 83 RegisterAliasingTrackerCache Cache(RegInfo, NoReservedReg); 84 ASSERT_THAT(&Cache.getRegister(llvm::X86::AX), 85 &Cache.getRegister(llvm::X86::AX)); 86 87 ASSERT_THAT(&Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID), 88 &Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID)); 89 } 90 91 } // namespace 92 } // namespace exegesis 93 } // namespace llvm 94