summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-06-13 16:07:36 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-06-13 16:07:36 +0000
commitde2ac17b7b945ff04bf687437861f26976efb658 (patch)
tree0b2788a67e80437d8a64a659065c6c924e8caea6 /llvm/lib
parent0bdafe5b63da626cbd5421b08c299b4dfeaaa39b (diff)
downloadbcm5719-llvm-de2ac17b7b945ff04bf687437861f26976efb658.tar.gz
bcm5719-llvm-de2ac17b7b945ff04bf687437861f26976efb658.zip
[Hexagon] Don't kill live registers when creating mux out of tfr
When a mux instruction is created from a pair of complementary conditional transfers, it can be placed at the location of either the earlier or the later of the transfers. Since it will use the operands of the original transfers, putting it in the earlier location may hoist a kill of a source register that was originally further down. Make sure the kill flag is removed if the register is still used afterwards. llvm-svn: 305300
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonGenMux.cpp22
-rw-r--r--llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp8
2 files changed, 22 insertions, 8 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonGenMux.cpp b/llvm/lib/Target/Hexagon/HexagonGenMux.cpp
index 3c37d9ebb0e..a2502ce5ec3 100644
--- a/llvm/lib/Target/Hexagon/HexagonGenMux.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonGenMux.cpp
@@ -59,9 +59,7 @@ namespace {
public:
static char ID;
- HexagonGenMux() : MachineFunctionPass(ID), HII(nullptr), HRI(nullptr) {
- initializeHexagonGenMuxPass(*PassRegistry::getPassRegistry());
- }
+ HexagonGenMux() : MachineFunctionPass(ID) {}
StringRef getPassName() const override {
return "Hexagon generate mux instructions";
@@ -79,8 +77,8 @@ namespace {
}
private:
- const HexagonInstrInfo *HII;
- const HexagonRegisterInfo *HRI;
+ const HexagonInstrInfo *HII = nullptr;
+ const HexagonRegisterInfo *HRI = nullptr;
struct CondsetInfo {
unsigned PredR = 0;
@@ -134,7 +132,7 @@ namespace {
} // end anonymous namespace
-INITIALIZE_PASS(HexagonGenMux, "hexagon-mux",
+INITIALIZE_PASS(HexagonGenMux, "hexagon-gen-mux",
"Hexagon generate mux instructions", false, false)
void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const {
@@ -297,12 +295,15 @@ bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) {
unsigned SR1 = Src1->isReg() ? Src1->getReg() : 0;
unsigned SR2 = Src2->isReg() ? Src2->getReg() : 0;
bool Failure = false, CanUp = true, CanDown = true;
+ bool Used1 = false, Used2 = false;
for (unsigned X = MinX+1; X < MaxX; X++) {
const DefUseInfo &DU = DUM.lookup(X);
if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) {
Failure = true;
break;
}
+ Used1 |= DU.Uses[SR1];
+ Used2 |= DU.Uses[SR2];
if (CanDown && DU.Defs[SR1])
CanDown = false;
if (CanUp && DU.Defs[SR2])
@@ -316,6 +317,15 @@ bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) {
// Prefer "down", since this will move the MUX farther away from the
// predicate definition.
MachineBasicBlock::iterator At = CanDown ? Def2 : Def1;
+ if (!CanDown) {
+ // If the MUX is placed "up", it shouldn't kill any source registers
+ // that are still used afterwards. We can reset the kill flags directly
+ // on the operands, because the source instructions will be erased.
+ if (Used1 && Src1->isReg())
+ Src1->setIsKill(false);
+ if (Used2 && Src2->isReg())
+ Src2->setIsKill(false);
+ }
ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2));
}
diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
index c757b6ecdd0..e507a797871 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -111,6 +111,7 @@ namespace llvm {
extern char &HexagonExpandCondsetsID;
void initializeHexagonExpandCondsetsPass(PassRegistry&);
void initializeHexagonLoopIdiomRecognizePass(PassRegistry&);
+ void initializeHexagonGenMuxPass(PassRegistry&);
void initializeHexagonOptAddrModePass(PassRegistry&);
Pass *createHexagonLoopIdiomPass();
@@ -152,8 +153,11 @@ static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
extern "C" void LLVMInitializeHexagonTarget() {
// Register the target.
RegisterTargetMachine<HexagonTargetMachine> X(getTheHexagonTarget());
- initializeHexagonLoopIdiomRecognizePass(*PassRegistry::getPassRegistry());
- initializeHexagonOptAddrModePass(*PassRegistry::getPassRegistry());
+
+ PassRegistry &PR = *PassRegistry::getPassRegistry();
+ initializeHexagonLoopIdiomRecognizePass(PR);
+ initializeHexagonGenMuxPass(PR);
+ initializeHexagonOptAddrModePass(PR);
}
HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT,
OpenPOWER on IntegriCloud