| 1 | //=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===// |
| 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 | // When the compiler is invoked with no small data, for instance, with the -G0 |
| 10 | // command line option, then all CONST* opcodes should be broken down into |
| 11 | // appropriate LO and HI instructions. This splitting is done by this pass. |
| 12 | // The only reason this is not done in the DAG lowering itself is that there |
| 13 | // is no simple way of getting the register allocator to allot the same hard |
| 14 | // register to the result of LO and HI instructions. This pass is always |
| 15 | // scheduled after register allocation. |
| 16 | // |
| 17 | //===----------------------------------------------------------------------===// |
| 18 | |
| 19 | #include "Hexagon.h" |
| 20 | #include "HexagonSubtarget.h" |
| 21 | #include "HexagonTargetMachine.h" |
| 22 | #include "HexagonTargetObjectFile.h" |
| 23 | #include "llvm/CodeGen/MachineFunctionPass.h" |
| 24 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 25 | #include "llvm/CodeGen/Passes.h" |
| 26 | #include "llvm/CodeGen/TargetInstrInfo.h" |
| 27 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
| 28 | |
| 29 | using namespace llvm; |
| 30 | |
| 31 | #define DEBUG_TYPE "xfer" |
| 32 | |
| 33 | namespace { |
| 34 | class HexagonSplitConst32AndConst64 : public MachineFunctionPass { |
| 35 | public: |
| 36 | static char ID; |
| 37 | HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {} |
| 38 | StringRef getPassName() const override { |
| 39 | return "Hexagon Split Const32s and Const64s" ; |
| 40 | } |
| 41 | bool runOnMachineFunction(MachineFunction &Fn) override; |
| 42 | MachineFunctionProperties getRequiredProperties() const override { |
| 43 | return MachineFunctionProperties().setNoVRegs(); |
| 44 | } |
| 45 | }; |
| 46 | } |
| 47 | |
| 48 | char HexagonSplitConst32AndConst64::ID = 0; |
| 49 | |
| 50 | INITIALIZE_PASS(HexagonSplitConst32AndConst64, "split-const-for-sdata" , |
| 51 | "Hexagon Split Const32s and Const64s" , false, false) |
| 52 | |
| 53 | bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { |
| 54 | auto &HST = Fn.getSubtarget<HexagonSubtarget>(); |
| 55 | auto &HTM = static_cast<const HexagonTargetMachine&>(Fn.getTarget()); |
| 56 | auto &TLOF = *HTM.getObjFileLowering(); |
| 57 | if (HST.useSmallData() && TLOF.isSmallDataEnabled(TM: HTM)) |
| 58 | return false; |
| 59 | |
| 60 | const TargetInstrInfo *TII = HST.getInstrInfo(); |
| 61 | const TargetRegisterInfo *TRI = HST.getRegisterInfo(); |
| 62 | |
| 63 | // Loop over all of the basic blocks |
| 64 | for (MachineBasicBlock &B : Fn) { |
| 65 | for (MachineInstr &MI : llvm::make_early_inc_range(Range&: B)) { |
| 66 | unsigned Opc = MI.getOpcode(); |
| 67 | |
| 68 | if (Opc == Hexagon::CONST32) { |
| 69 | Register DestReg = MI.getOperand(i: 0).getReg(); |
| 70 | uint64_t ImmValue = MI.getOperand(i: 1).getImm(); |
| 71 | const DebugLoc &DL = MI.getDebugLoc(); |
| 72 | BuildMI(BB&: B, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Hexagon::A2_tfrsi), DestReg) |
| 73 | .addImm(Val: ImmValue); |
| 74 | B.erase(I: &MI); |
| 75 | } else if (Opc == Hexagon::CONST64) { |
| 76 | Register DestReg = MI.getOperand(i: 0).getReg(); |
| 77 | int64_t ImmValue = MI.getOperand(i: 1).getImm(); |
| 78 | const DebugLoc &DL = MI.getDebugLoc(); |
| 79 | Register DestLo = TRI->getSubReg(Reg: DestReg, Idx: Hexagon::isub_lo); |
| 80 | Register DestHi = TRI->getSubReg(Reg: DestReg, Idx: Hexagon::isub_hi); |
| 81 | |
| 82 | int32_t LowWord = (ImmValue & 0xFFFFFFFF); |
| 83 | int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF; |
| 84 | |
| 85 | BuildMI(BB&: B, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Hexagon::A2_tfrsi), DestReg: DestLo) |
| 86 | .addImm(Val: LowWord); |
| 87 | BuildMI(BB&: B, I&: MI, MIMD: DL, MCID: TII->get(Opcode: Hexagon::A2_tfrsi), DestReg: DestHi) |
| 88 | .addImm(Val: HighWord); |
| 89 | B.erase(I: &MI); |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | return true; |
| 95 | } |
| 96 | |
| 97 | |
| 98 | //===----------------------------------------------------------------------===// |
| 99 | // Public Constructor Functions |
| 100 | //===----------------------------------------------------------------------===// |
| 101 | FunctionPass *llvm::createHexagonSplitConst32AndConst64() { |
| 102 | return new HexagonSplitConst32AndConst64(); |
| 103 | } |
| 104 | |