aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/DFAPacketizer.cpp89
-rw-r--r--lib/Target/Hexagon/CMakeLists.txt9
-rw-r--r--lib/Target/Hexagon/Hexagon.h3
-rw-r--r--lib/Target/Hexagon/HexagonAsmPrinter.cpp55
-rw-r--r--lib/Target/Hexagon/HexagonCallingConv.td8
-rw-r--r--lib/Target/Hexagon/HexagonCopyToCombine.cpp475
-rw-r--r--lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp14
-rw-r--r--lib/Target/Hexagon/HexagonISelDAGToDAG.cpp38
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp367
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h4
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormats.td96
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormatsV4.td27
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp1075
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.h18
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td1855
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV3.td51
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td2913
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV5.td626
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsics.td1237
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsicsDerived.td34
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsicsV5.td395
-rw-r--r--lib/Target/Hexagon/HexagonMCInst.h41
-rw-r--r--lib/Target/Hexagon/HexagonMCInstLower.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonNewValueJump.cpp649
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp21
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.td12
-rw-r--r--lib/Target/Hexagon/HexagonSchedule.td31
-rw-r--r--lib/Target/Hexagon/HexagonScheduleV4.td35
-rw-r--r--lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp144
-rw-r--r--lib/Target/Hexagon/HexagonSubtarget.cpp17
-rw-r--r--lib/Target/Hexagon/HexagonSubtarget.h8
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp10
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp3642
-rw-r--r--lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp74
-rw-r--r--lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h2
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt2
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h31
37 files changed, 2017 insertions, 12093 deletions
diff --git a/lib/CodeGen/DFAPacketizer.cpp b/lib/CodeGen/DFAPacketizer.cpp
index bfbe779099..5ff641c7c8 100644
--- a/lib/CodeGen/DFAPacketizer.cpp
+++ b/lib/CodeGen/DFAPacketizer.cpp
@@ -23,10 +23,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/MC/MCInstrItineraries.h"
using namespace llvm;
@@ -100,17 +100,17 @@ void DFAPacketizer::reserveResources(llvm::MachineInstr *MI) {
reserveResources(&MID);
}
-namespace llvm {
+namespace {
// DefaultVLIWScheduler - This class extends ScheduleDAGInstrs and overrides
// Schedule method to build the dependence graph.
class DefaultVLIWScheduler : public ScheduleDAGInstrs {
public:
DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
- MachineDominatorTree &MDT, bool IsPostRA);
+ MachineDominatorTree &MDT, bool IsPostRA);
// Schedule - Actual scheduling work.
void schedule();
};
-}
+} // end anonymous namespace
DefaultVLIWScheduler::DefaultVLIWScheduler(
MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
@@ -129,25 +129,49 @@ VLIWPacketizerList::VLIWPacketizerList(
bool IsPostRA) : TM(MF.getTarget()), MF(MF) {
TII = TM.getInstrInfo();
ResourceTracker = TII->CreateTargetScheduleState(&TM, 0);
- VLIWScheduler = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA);
+ SchedulerImpl = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA);
}
// VLIWPacketizerList Dtor
VLIWPacketizerList::~VLIWPacketizerList() {
- if (VLIWScheduler)
- delete VLIWScheduler;
+ delete SchedulerImpl;
+ delete ResourceTracker;
+}
+
+// ignorePseudoInstruction - ignore pseudo instructions.
+bool VLIWPacketizerList::ignorePseudoInstruction(MachineInstr *MI,
+ MachineBasicBlock *MBB) {
+ if (MI->isDebugValue())
+ return true;
+
+ if (TII->isSchedulingBoundary(MI, MBB, MF))
+ return true;
+
+ return false;
+}
+
+// isSoloInstruction - return true if instruction I must end previous
+// packet.
+bool VLIWPacketizerList::isSoloInstruction(MachineInstr *I) {
+ if (I->isInlineAsm())
+ return true;
+
+ return false;
+}
- if (ResourceTracker)
- delete ResourceTracker;
+// addToPacket - Add I to the current packet and reserve resource.
+void VLIWPacketizerList::addToPacket(MachineInstr *MI) {
+ CurrentPacketMIs.push_back(MI);
+ ResourceTracker->reserveResources(MI);
}
// endPacket - End the current packet, bundle packet instructions and reset
// DFA state.
void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
- MachineInstr *MI) {
+ MachineInstr *I) {
if (CurrentPacketMIs.size() > 1) {
MachineInstr *MIFirst = CurrentPacketMIs.front();
- finalizeBundle(*MBB, MIFirst, MI);
+ finalizeBundle(*MBB, MIFirst, I);
}
CurrentPacketMIs.clear();
ResourceTracker->clearResources();
@@ -157,36 +181,31 @@ void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
MachineBasicBlock::iterator BeginItr,
MachineBasicBlock::iterator EndItr) {
- assert(VLIWScheduler && "VLIW Scheduler is not initialized!");
- VLIWScheduler->enterRegion(MBB, BeginItr, EndItr, MBB->size());
- VLIWScheduler->schedule();
- VLIWScheduler->exitRegion();
-
- // Generate MI -> SU map.
- //std::map <MachineInstr*, SUnit*> MIToSUnit;
- MIToSUnit.clear();
- for (unsigned i = 0, e = VLIWScheduler->SUnits.size(); i != e; ++i) {
- SUnit *SU = &VLIWScheduler->SUnits[i];
- MIToSUnit[SU->getInstr()] = SU;
- }
+ assert(MBB->end() == EndItr && "Bad EndIndex");
+
+ SchedulerImpl->enterRegion(MBB, BeginItr, EndItr, MBB->size());
+
+ // Build the DAG without reordering instructions.
+ SchedulerImpl->schedule();
+
+ // Remember scheduling units.
+ SUnits = SchedulerImpl->SUnits;
// The main packetizer loop.
for (; BeginItr != EndItr; ++BeginItr) {
MachineInstr *MI = BeginItr;
- this->initPacketizerState();
+ // Ignore pseudo instructions.
+ if (ignorePseudoInstruction(MI, MBB))
+ continue;
// End the current packet if needed.
- if (this->isSoloInstruction(MI)) {
+ if (isSoloInstruction(MI)) {
endPacket(MBB, MI);
continue;
}
- // Ignore pseudo instructions.
- if (this->ignorePseudoInstruction(MI, MBB))
- continue;
-
- SUnit *SUI = MIToSUnit[MI];
+ SUnit *SUI = SchedulerImpl->getSUnit(MI);
assert(SUI && "Missing SUnit Info!");
// Ask DFA if machine resource is available for MI.
@@ -196,13 +215,13 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(),
VE = CurrentPacketMIs.end(); VI != VE; ++VI) {
MachineInstr *MJ = *VI;
- SUnit *SUJ = MIToSUnit[MJ];
+ SUnit *SUJ = SchedulerImpl->getSUnit(MJ);
assert(SUJ && "Missing SUnit Info!");
// Is it legal to packetize SUI and SUJ together.
- if (!this->isLegalToPacketizeTogether(SUI, SUJ)) {
+ if (!isLegalToPacketizeTogether(SUI, SUJ)) {
// Allow packetization if dependency can be pruned.
- if (!this->isLegalToPruneDependencies(SUI, SUJ)) {
+ if (!isLegalToPruneDependencies(SUI, SUJ)) {
// End the packet if dependency cannot be pruned.
endPacket(MBB, MI);
break;
@@ -215,9 +234,11 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
}
// Add MI to the current packet.
- BeginItr = this->addToPacket(MI);
+ addToPacket(MI);
} // For all instructions in BB.
// End any packet left behind.
endPacket(MBB, EndItr);
+
+ SchedulerImpl->exitRegion();
}
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt
index 7f4192c0dd..af9e8136bf 100644
--- a/lib/Target/Hexagon/CMakeLists.txt
+++ b/lib/Target/Hexagon/CMakeLists.txt
@@ -11,15 +11,15 @@ add_public_tablegen_target(HexagonCommonTableGen)
add_llvm_target(HexagonCodeGen
HexagonAsmPrinter.cpp
- HexagonCFGOptimizer.cpp
HexagonCallingConvLower.cpp
+ HexagonCFGOptimizer.cpp
HexagonExpandPredSpillCode.cpp
HexagonFrameLowering.cpp
HexagonHardwareLoops.cpp
+ HexagonMCInstLower.cpp
+ HexagonInstrInfo.cpp
HexagonISelDAGToDAG.cpp
HexagonISelLowering.cpp
- HexagonInstrInfo.cpp
- HexagonMCInstLower.cpp
HexagonPeephole.cpp
HexagonRegisterInfo.cpp
HexagonRemoveSZExtArgs.cpp
@@ -28,9 +28,6 @@ add_llvm_target(HexagonCodeGen
HexagonSubtarget.cpp
HexagonTargetMachine.cpp
HexagonTargetObjectFile.cpp
- HexagonVLIWPacketizer.cpp
- HexagonNewValueJump.cpp
- HexagonCopyToCombine.cpp
)
add_subdirectory(TargetInfo)
diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h
index 2738df3717..0808323336 100644
--- a/lib/Target/Hexagon/Hexagon.h
+++ b/lib/Target/Hexagon/Hexagon.h
@@ -40,9 +40,6 @@ namespace llvm {
FunctionPass *createHexagonHardwareLoops();
FunctionPass *createHexagonPeephole();
FunctionPass *createHexagonFixupHwLoops();
- FunctionPass *createHexagonNewValueJump();
- FunctionPass *createHexagonCopyToCombine();
- FunctionPass *createHexagonPacketizer();
/* TODO: object output.
MCCodeEmitter *createHexagonMCCodeEmitter(const Target &,
diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
index 2cc8b814a0..39bf45d2d7 100644
--- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp
+++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
@@ -13,11 +13,11 @@
//
//===----------------------------------------------------------------------===//
+
#define DEBUG_TYPE "asm-printer"
#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
#include "HexagonMachineFunctionInfo.h"
-#include "HexagonMCInst.h"
#include "HexagonTargetMachine.h"
#include "HexagonSubtarget.h"
#include "InstPrinter/HexagonInstPrinter.h"
@@ -54,7 +54,6 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
-#include <map>
using namespace llvm;
@@ -78,7 +77,8 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
- default: llvm_unreachable("<unknown operand type>");
+ default:
+ assert(0 && "<unknown operand type>");
case MachineOperand::MO_Register:
O << HexagonInstPrinter::getRegisterName(MO.getReg());
return;
@@ -196,45 +196,10 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI,
/// the current output stream.
///
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
- if (MI->isBundle()) {
- std::vector<const MachineInstr*> BundleMIs;
-
- const MachineBasicBlock *MBB = MI->getParent();
- MachineBasicBlock::const_instr_iterator MII = MI;
- ++MII;
- unsigned int IgnoreCount = 0;
- while (MII != MBB->end() && MII->isInsideBundle()) {
- const MachineInstr *MInst = MII;
- if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
- MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
- IgnoreCount++;
- ++MII;
- continue;
- }
- //BundleMIs.push_back(&*MII);
- BundleMIs.push_back(MInst);
- ++MII;
- }
- unsigned Size = BundleMIs.size();
- assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
- for (unsigned Index = 0; Index < Size; Index++) {
- HexagonMCInst MCI;
- MCI.setStartPacket(Index == 0);
- MCI.setEndPacket(Index == (Size-1));
-
- HexagonLowerToMC(BundleMIs[Index], MCI, *this);
- OutStreamer.EmitInstruction(MCI);
- }
- }
- else {
- HexagonMCInst MCI;
- if (MI->getOpcode() == Hexagon::ENDLOOP0) {
- MCI.setStartPacket(true);
- MCI.setEndPacket(true);
- }
- HexagonLowerToMC(MI, MCI, *this);
- OutStreamer.EmitInstruction(MCI);
- }
+ MCInst MCI;
+
+ HexagonLowerToMC(MI, MCI, *this);
+ OutStreamer.EmitInstruction(MCI);
return;
}
@@ -277,17 +242,17 @@ void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) &&
- "Expecting jump table index");
+ "Expecting jump table index");
// Hexagon_TODO: Do we need name mangling?
O << *GetJTISymbol(MO.getIndex());
}
void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo,
- raw_ostream &O) {
+ raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) &&
- "Expecting constant pool index");
+ "Expecting constant pool index");
// Hexagon_TODO: Do we need name mangling?
O << *GetCPISymbol(MO.getIndex());
diff --git a/lib/Target/Hexagon/HexagonCallingConv.td b/lib/Target/Hexagon/HexagonCallingConv.td
index e61b2a7a58..bd9608bdb0 100644
--- a/lib/Target/Hexagon/HexagonCallingConv.td
+++ b/lib/Target/Hexagon/HexagonCallingConv.td
@@ -17,8 +17,8 @@
// Hexagon 32-bit C return-value convention.
def RetCC_Hexagon32 : CallingConv<[
- CCIfType<[i32, f32], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
- CCIfType<[i64, f64], CCAssignToReg<[D0, D1, D2]>>,
+ CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
+ CCIfType<[i64], CCAssignToReg<[D0, D1, D2]>>,
// Alternatively, they are assigned to the stack in 4-byte aligned units.
CCAssignToStack<4, 4>
@@ -27,8 +27,8 @@ def RetCC_Hexagon32 : CallingConv<[
// Hexagon 32-bit C Calling convention.
def CC_Hexagon32 : CallingConv<[
// All arguments get passed in integer registers if there is space.
- CCIfType<[f32, i32, i16, i8], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
- CCIfType<[f64, i64], CCAssignToReg<[D0, D1, D2]>>,
+ CCIfType<[i32, i16, i8], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
+ CCIfType<[i64], CCAssignToReg<[D0, D1, D2]>>,
// Alternatively, they are assigned to the stack in 4-byte aligned units.
CCAssignToStack<4, 4>
diff --git a/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/lib/Target/Hexagon/HexagonCopyToCombine.cpp
deleted file mode 100644
index e93d278c82..0000000000
--- a/lib/Target/Hexagon/HexagonCopyToCombine.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-//===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// This pass replaces transfer instructions by combine instructions.
-// We walk along a basic block and look for two combinable instructions and try
-// to move them together. If we can move them next to each other we do so and
-// replace them with a combine instruction.
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "hexagon-copy-combine"
-
-#include "llvm/PassSupport.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include "Hexagon.h"
-#include "HexagonInstrInfo.h"
-#include "HexagonRegisterInfo.h"
-#include "HexagonSubtarget.h"
-#include "HexagonTargetMachine.h"
-#include "HexagonMachineFunctionInfo.h"
-
-using namespace llvm;
-
-static
-cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines",
- cl::Hidden, cl::ZeroOrMore,
- cl::init(false),
- cl::desc("Disable merging into combines"));
-
-namespace {
-
-class HexagonCopyToCombine : public MachineFunctionPass {
- const HexagonInstrInfo *TII;
- const TargetRegisterInfo *TRI;
-public:
- static char ID;
-
- HexagonCopyToCombine() : MachineFunctionPass(ID) { }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-
- const char *getPassName() const {
- return "Hexagon Copy-To-Combine Pass";
- }
-
- virtual bool runOnMachineFunction(MachineFunction &Fn);
-
-private:
- MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1);
-
- void combine(MachineInstr *I1, MachineInstr *I2,
- MachineBasicBlock::iterator &MI, bool DoInsertAtI1);
-
- bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2,
- unsigned I1DestReg, unsigned I2DestReg,
- bool &DoInsertAtI1);
-
- void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,
- MachineOperand &HiOperand, MachineOperand &LoOperand);
-
- void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,
- MachineOperand &HiOperand, MachineOperand &LoOperand);
-
- void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,
- MachineOperand &HiOperand, MachineOperand &LoOperand);
-
- void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,
- MachineOperand &HiOperand, MachineOperand &LoOperand);
-};
-
-} // End anonymous namespace.
-
-char HexagonCopyToCombine::ID = 0;
-
-static bool isCombinableInstType(MachineInstr *MI,
- const HexagonInstrInfo *TII) {
- switch(MI->getOpcode()) {
- case Hexagon::TFR: {
- // A COPY instruction can be combined if its arguments are IntRegs (32bit).
- assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg());
-
- unsigned DestReg = MI->getOperand(0).getReg();
- unsigned SrcReg = MI->getOperand(1).getReg();
- return Hexagon::IntRegsRegClass.contains(DestReg) &&
- Hexagon::IntRegsRegClass.contains(SrcReg);
- }
-
- case Hexagon::TFRI: {
- // A transfer-immediate can be combined if its argument is a signed 8bit
- // value.
- assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
- unsigned DestReg = MI->getOperand(0).getReg();
- return Hexagon::IntRegsRegClass.contains(DestReg) &&
- isInt<8>(MI->getOperand(1).getImm());
- }
- default:
- break;
- }
-
- return false;
-}
-
-
-/// areCombinableOperations - Returns true if the two instruction can be merge
-/// into a combine (ignoring register constraints).
-static bool areCombinableOperations(const TargetRegisterInfo *TRI,
- MachineInstr *I1, MachineInstr *I2) {
- assert((I1->getOpcode() == Hexagon::TFR ||
- I1->getOpcode() == Hexagon::TFRI) &&
- (I2->getOpcode() == Hexagon::TFR ||
- I2->getOpcode() == Hexagon::TFRI) &&
- "Assume individual instructions are of a combinable type");
-
- const HexagonRegisterInfo *QRI =
- static_cast<const HexagonRegisterInfo *>(TRI);
-
- // V4 added some combine variations (mixed immediate and register source
- // operands), if we are on < V4 we can only combine 2 register-to-register
- // moves and 2 immediate-to-register moves.
- if (QRI->Subtarget.getHexagonArchVersion() < HexagonSubtarget::V4)
- return I1->getOpcode() == I2->getOpcode();
-
- return true;
-}
-
-static bool isEvenReg(unsigned Reg) {
- assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
- Hexagon::IntRegsRegClass.contains(Reg));
- return (Reg - Hexagon::R0) % 2 == 0;
-}
-
-static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) {
- for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
- MachineOperand &Op = MI->getOperand(I);
- if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill())
- continue;
- Op.setIsKill(false);
- }
-}
-
-/// isUnsafeToMoveAccross - Returns true if it is unsafe to move a copy
-/// instruction from \p UseReg to \p DestReg over the instruction \p I.
-bool isUnsafeToMoveAccross(MachineInstr *I, unsigned UseReg, unsigned DestReg,
- const TargetRegisterInfo *TRI) {
- return (UseReg && (I->modifiesRegister(UseReg, TRI))) ||
- I->modifiesRegister(DestReg, TRI) ||
- I->readsRegister(DestReg, TRI) ||
- I->hasUnmodeledSideEffects() ||
- I->isInlineAsm() || I->isDebugValue();
-}
-
-/// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such
-/// that the two instructions can be paired in a combine.
-bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1,
- MachineInstr *I2,
- unsigned I1DestReg,
- unsigned I2DestReg,
- bool &DoInsertAtI1) {
- bool isSafe = true;
-
- // First try to move I2 towards I1.
- {
- // A reverse_iterator instantiated like below starts before I2, and I1
- // respectively.
- // Look at instructions I in between I2 and (including) I1.
- MachineBasicBlock::reverse_iterator I(I2),
- End = MachineBasicBlock::reverse_iterator(I1);
- bool IsImmUseReg = I2->getOperand(1).isImm();
- unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg();
-
- // If I2 kills its operand and we move I2 over an instruction that also
- // uses I2's use reg we need to modify that (first) instruction to now kill
- // this reg.
- unsigned KilledOperand = 0;
- if (I2->killsRegister(I2UseReg))
- KilledOperand = I2UseReg;
- MachineInstr *KillingInstr = 0;
-
- for (; I != End; ++I) {
- // If the intervening instruction I:
- // * modifies I2's use reg
- // * modifies I2's def reg
- // * reads I2's def reg
- // * or has unmodelled side effects
- // we can't move I2 across it.
- if (isUnsafeToMoveAccross(&*I, I2UseReg, I2DestReg, TRI)) {
- isSafe = false;
- break;
- }
-
- // Update first use of the killed operand.
- if (!KillingInstr && KilledOperand &&
- I->readsRegister(KilledOperand, TRI))
- KillingInstr = &*I;
- }
- if (isSafe) {
- // Update the intermediate instruction to with the kill flag.
- if (KillingInstr) {
- bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);
- assert(Added && "Must successfully update kill flag");
- (void)Added;
- removeKillInfo(I2, KilledOperand);
- }
- DoInsertAtI1 = true;
- return true;
- }
- }
-
- // Try to move I1 towards I2.
- {
- // Look at instructions I in between I1 and (including) I2.
- MachineBasicBlock::iterator I(I1),
- End(llvm::next(MachineBasicBlock::iterator(I2)));
- bool IsImmUseReg = I1->getOperand(1).isImm();
- unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg();
- // Track killed operands. If we move accross an instruction that kills our
- // operand, we need to update the kill information on the moved I1. It kills
- // the operand now.
- MachineInstr *KillingInstr = 0;
- unsigned KilledOperand = 0;
-
- while(++I != End) {
- // If the intervening instruction I:
- // * modifies I1's use reg
- // * modifies I1's def reg
- // * reads I1's def reg
- // * or has unmodelled side effects
- // We introduce this special case because llvm has no api to remove a
- // kill flag for a register (a removeRegisterKilled() analogous to
- // addRegisterKilled) that handles aliased register correctly.
- // * or has a killed aliased register use of I1's use reg
- // %D4<def> = TFRI64 16
- // %R6<def> = TFR %R9
- // %R8<def> = KILL %R8, %D4<imp-use,kill>
- // If we want to move R6 = across the KILL instruction we would have
- // to remove the %D4<imp-use,kill> operand. For now, we are
- // conservative and disallow the move.
- // we can't move I1 across it.
- if (isUnsafeToMoveAccross(I, I1UseReg, I1DestReg, TRI) ||
- // Check for an aliased register kill. Bail out if we see one.
- (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI)))
- return false;
-
- // Check for an exact kill (registers match).
- if (I1UseReg && I->killsRegister(I1UseReg)) {
- assert(KillingInstr == 0 && "Should only see one killing instruction");
- KilledOperand = I1UseReg;
- KillingInstr = &*I;
- }
- }
- if (KillingInstr) {
- removeKillInfo(KillingInstr, KilledOperand);
- // Update I1 to set the kill flag. This flag will later be picked up by
- // the new COMBINE instruction.
- bool Added = I1->addRegisterKilled(KilledOperand, TRI);
- assert(Added && "Must successfully update kill flag");
- (void)Added;
- }
- DoInsertAtI1 = false;
- }
-
- return true;
-}
-
-bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
-
- if (IsCombinesDisabled) return false;
-
- bool HasChanged = false;
-
- // Get target info.
- TRI = MF.getTarget().getRegisterInfo();
- TII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
-
- // Traverse basic blocks.
- for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE;
- ++BI) {
- // Traverse instructions in basic block.
- for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end();
- MI != End;) {
- MachineInstr *I1 = MI++;
-
- // Ignore instructions that are not combinable.
- if (!isCombinableInstType(I1, TII))
- continue;
-
- // Find a second instruction that can be merged into a combine
- // instruction.
- bool DoInsertAtI1 = false;
- MachineInstr *I2 = findPairable(I1, DoInsertAtI1);
- if (I2) {
- HasChanged = true;
- combine(I1, I2, MI, DoInsertAtI1);
- }
- }
- }
-
- return HasChanged;
-}
-
-/// findPairable - Returns an instruction that can be merged with \p I1 into a
-/// COMBINE instruction or 0 if no such instruction can be found. Returns true
-/// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1
-/// false if the combine must be inserted at the returned instruction.
-MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1,
- bool &DoInsertAtI1) {
- MachineBasicBlock::iterator I2 = llvm::next(MachineBasicBlock::iterator(I1));
- unsigned I1DestReg = I1->getOperand(0).getReg();
-
- for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End;
- ++I2) {
- // Bail out early if we see a second definition of I1DestReg.
- if (I2->modifiesRegister(I1DestReg, TRI))
- break;
-
- // Ignore non-combinable instructions.
- if (!isCombinableInstTy