1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
//=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// When the compiler is invoked with no small data, for instance, with the -G0
// command line option, then all CONST32_* opcodes should be broken down into
// appropriate LO and HI instructions. This splitting is done by this pass.
// The only reason this is not done in the DAG lowering itself is that there
// is no simple way of getting the register allocator to allot the same hard
// register to the result of LO and HI instructions. This pass is always
// scheduled after register allocation.
//
//===----------------------------------------------------------------------===//
#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "HexagonTargetObjectFile.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/LatencyPriorityQueue.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <map>
using namespace llvm;
#define DEBUG_TYPE "xfer"
namespace {
class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
const HexagonTargetMachine &QTM;
public:
static char ID;
HexagonSplitConst32AndConst64(const HexagonTargetMachine &TM)
: MachineFunctionPass(ID), QTM(TM) {}
const char *getPassName() const override {
return "Hexagon Split Const32s and Const64s";
}
bool runOnMachineFunction(MachineFunction &Fn) override;
};
char HexagonSplitConst32AndConst64::ID = 0;
bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
const HexagonTargetObjectFile &TLOF =
(const HexagonTargetObjectFile &)
QTM.getTargetLowering()->getObjFileLowering();
if (TLOF.IsSmallDataEnabled())
return true;
const TargetInstrInfo *TII = QTM.getInstrInfo();
// Loop over all of the basic blocks
for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
MBBb != MBBe; ++MBBb) {
MachineBasicBlock* MBB = MBBb;
// Traverse the basic block
MachineBasicBlock::iterator MII = MBB->begin();
MachineBasicBlock::iterator MIE = MBB->end ();
while (MII != MIE) {
MachineInstr *MI = MII;
int Opc = MI->getOpcode();
if (Opc == Hexagon::CONST32_set) {
int DestReg = MI->getOperand(0).getReg();
MachineOperand &Symbol = MI->getOperand (1);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::LO), DestReg).addOperand(Symbol);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::HI), DestReg).addOperand(Symbol);
// MBB->erase returns the iterator to the next instruction, which is the
// one we want to process next
MII = MBB->erase (MI);
continue;
}
else if (Opc == Hexagon::CONST32_set_jt) {
int DestReg = MI->getOperand(0).getReg();
MachineOperand &Symbol = MI->getOperand (1);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::LO_jt), DestReg).addOperand(Symbol);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::HI_jt), DestReg).addOperand(Symbol);
// MBB->erase returns the iterator to the next instruction, which is the
// one we want to process next
MII = MBB->erase (MI);
continue;
}
else if (Opc == Hexagon::CONST32_Label) {
int DestReg = MI->getOperand(0).getReg();
MachineOperand &Symbol = MI->getOperand (1);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::LO_label), DestReg).addOperand(Symbol);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::HI_label), DestReg).addOperand(Symbol);
// MBB->erase returns the iterator to the next instruction, which is the
// one we want to process next
MII = MBB->erase (MI);
continue;
}
else if (Opc == Hexagon::CONST32_Int_Real) {
int DestReg = MI->getOperand(0).getReg();
int64_t ImmValue = MI->getOperand(1).getImm ();
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::LOi), DestReg).addImm(ImmValue);
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::HIi), DestReg).addImm(ImmValue);
MII = MBB->erase (MI);
continue;
}
else if (Opc == Hexagon::CONST64_Int_Real) {
int DestReg = MI->getOperand(0).getReg();
int64_t ImmValue = MI->getOperand(1).getImm ();
unsigned DestLo =
QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_loreg);
unsigned DestHi =
QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_hireg);
int32_t LowWord = (ImmValue & 0xFFFFFFFF);
int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
// Lower Registers Lower Half
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::LOi), DestLo).addImm(LowWord);
// Lower Registers Higher Half
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::HIi), DestLo).addImm(LowWord);
// Higher Registers Lower Half
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::LOi), DestHi).addImm(HighWord);
// Higher Registers Higher Half.
BuildMI (*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::HIi), DestHi).addImm(HighWord);
MII = MBB->erase (MI);
continue;
}
++MII;
}
}
return true;
}
}
//===----------------------------------------------------------------------===//
// Public Constructor Functions
//===----------------------------------------------------------------------===//
FunctionPass *
llvm::createHexagonSplitConst32AndConst64(const HexagonTargetMachine &TM) {
return new HexagonSplitConst32AndConst64(TM);
}
|