//
//===----------------------------------------------------------------------===//
-#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "HexagonTargetObjectFile.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/Debug.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
}
namespace {
-
-class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
- public:
+ class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
+ public:
static char ID;
- HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {}
-
+ HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {
+ PassRegistry &R = *PassRegistry::getPassRegistry();
+ initializeHexagonSplitConst32AndConst64Pass(R);
+ }
const char *getPassName() const override {
return "Hexagon Split Const32s and Const64s";
}
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::AllVRegsAllocated);
}
-};
-
+ };
+}
char HexagonSplitConst32AndConst64::ID = 0;
+INITIALIZE_PASS(HexagonSplitConst32AndConst64, "split-const-for-sdata",
+ "Hexagon Split Const32s and Const64s", false, false)
bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
-
const HexagonTargetObjectFile &TLOF =
*static_cast<const HexagonTargetObjectFile *>(
Fn.getTarget().getObjFileLowering());
const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
// 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 && MI.getOperand(1).isBlockAddress()) {
- 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) {
- int DestReg = MI.getOperand(0).getReg();
-
- // We have to convert an FP immediate into its corresponding integer
- // representation
- int64_t ImmValue = MI.getOperand(1).getImm();
- BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi),
- DestReg)
+ for (MachineBasicBlock &B : Fn) {
+ for (auto I = B.begin(), E = B.end(); I != E; ) {
+ MachineInstr &MI = *I;
+ ++I;
+ unsigned Opc = MI.getOpcode();
+
+ if (Opc == Hexagon::CONST32) {
+ unsigned DestReg = MI.getOperand(0).getReg();
+ uint64_t ImmValue = MI.getOperand(1).getImm();
+ const DebugLoc &DL = MI.getDebugLoc();
+ BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestReg)
.addImm(ImmValue);
- MII = MBB->erase(&MI);
- continue;
- }
- else if (Opc == Hexagon::CONST64) {
- int DestReg = MI.getOperand(0).getReg();
+ B.erase(&MI);
+ } else if (Opc == Hexagon::CONST64) {
+ unsigned DestReg = MI.getOperand(0).getReg();
int64_t ImmValue = MI.getOperand(1).getImm();
+ const DebugLoc &DL = MI.getDebugLoc();
unsigned DestLo = TRI->getSubReg(DestReg, Hexagon::subreg_loreg);
unsigned DestHi = TRI->getSubReg(DestReg, Hexagon::subreg_hireg);
int32_t LowWord = (ImmValue & 0xFFFFFFFF);
int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
- BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi),
- DestLo)
+ BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestLo)
.addImm(LowWord);
- BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi),
- DestHi)
+ BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestHi)
.addImm(HighWord);
- MII = MBB->erase(&MI);
- continue;
+ B.erase(&MI);
}
- ++MII;
}
}
return true;
}
-}
//===----------------------------------------------------------------------===//
// Public Constructor Functions
//===----------------------------------------------------------------------===//
-FunctionPass *
-llvm::createHexagonSplitConst32AndConst64() {
+FunctionPass *llvm::createHexagonSplitConst32AndConst64() {
return new HexagonSplitConst32AndConst64();
}
-; RUN: llc -march=hexagon -mcpu=hexagonv5 -hexagon-small-data-threshold=0 < %s | FileCheck %s
+; RUN: llc -march=hexagon -hexagon-small-data-threshold=0 < %s | FileCheck %s
-; Check that CONST32/CONST64 instructions are 'not' generated when
-; small-data-threshold is set to 0.
+; Check that CONST32/CONST64 instructions are 'not' generated when the
+; small data threshold is set to 0.
-; with immediate value.
@a = external global i32
@b = external global i32
@la = external global i64
@lb = external global i64
-define void @test1() nounwind {
+; CHECK-LABEL: test1:
; CHECK-NOT: CONST32
+define void @test1() nounwind {
entry:
+ br label %block
+block:
store i32 12345670, i32* @a, align 4
- store i32 12345670, i32* @b, align 4
+ %q = ptrtoint i8* blockaddress (@test1, %block) to i32
+ store i32 %q, i32* @b, align 4
ret void
}
-define void @test2() nounwind {
+; CHECK-LABEL: test2:
; CHECK-NOT: CONST64
+define void @test2() nounwind {
entry:
store i64 1234567890123, i64* @la, align 8
store i64 1234567890123, i64* @lb, align 8