Skip to content

Commit 86f218e

Browse files
author
Colin LeMahieu
committed
[Hexagon] Adding basic relaxation functionality.
llvm-svn: 238660
1 parent a01780f commit 86f218e

File tree

3 files changed

+157
-6
lines changed

3 files changed

+157
-6
lines changed

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp

Lines changed: 123 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,27 @@
77
//
88
//===----------------------------------------------------------------------===//
99

10+
#include "Hexagon.h"
11+
#include "HexagonFixupKinds.h"
1012
#include "HexagonMCTargetDesc.h"
13+
#include "MCTargetDesc/HexagonBaseInfo.h"
14+
#include "MCTargetDesc/HexagonMCInstrInfo.h"
1115
#include "llvm/MC/MCAsmBackend.h"
16+
#include "llvm/MC/MCAssembler.h"
1217
#include "llvm/MC/MCELFObjectWriter.h"
1318

1419
using namespace llvm;
20+
using namespace Hexagon;
1521

1622
namespace {
1723

1824
class HexagonAsmBackend : public MCAsmBackend {
25+
mutable uint64_t relaxedCnt;
26+
std::unique_ptr <MCInstrInfo> MCII;
27+
std::unique_ptr <MCInst *> RelaxTarget;
1928
public:
20-
HexagonAsmBackend(Target const & /*T*/) {}
29+
HexagonAsmBackend(Target const & /*T*/) :
30+
MCII (createHexagonMCInstrInfo()), RelaxTarget(new MCInst *){}
2131

2232
unsigned getNumFixupKinds() const override { return 0; }
2333

@@ -27,14 +37,121 @@ class HexagonAsmBackend : public MCAsmBackend {
2737
return;
2838
}
2939

30-
bool mayNeedRelaxation(MCInst const & /*Inst*/) const override {
40+
bool isInstRelaxable(MCInst const &HMI) const {
41+
const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
42+
assert(&MCID && "invalid instruction");
43+
44+
bool Relaxable = false;
45+
// Branches and loop-setup insns are handled as necessary by relaxation.
46+
if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ ||
47+
(llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNV &&
48+
MCID.isBranch()) ||
49+
(llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR &&
50+
HMI.getOpcode() != Hexagon::C4_addipc))
51+
if (HexagonMCInstrInfo::isExtendable(*MCII, HMI))
52+
Relaxable = true;
53+
54+
return Relaxable;
55+
}
56+
57+
/// MayNeedRelaxation - Check whether the given instruction may need
58+
/// relaxation.
59+
///
60+
/// \param Inst - The instruction to test.
61+
bool mayNeedRelaxation(MCInst const &Inst) const {
62+
assert(HexagonMCInstrInfo::isBundle(Inst));
63+
bool PreviousIsExtender = false;
64+
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
65+
auto const &Inst = *I.getInst();
66+
if (!PreviousIsExtender) {
67+
if (isInstRelaxable(Inst))
68+
return true;
69+
}
70+
PreviousIsExtender = HexagonMCInstrInfo::isImmext(Inst);
71+
}
72+
return false;
73+
}
74+
75+
/// fixupNeedsRelaxation - Target specific predicate for whether a given
76+
/// fixup requires the associated instruction to be relaxed.
77+
bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
78+
uint64_t Value,
79+
const MCRelaxableFragment *DF,
80+
const MCAsmLayout &Layout) const {
81+
MCInst const &MCB = DF->getInst();
82+
assert(HexagonMCInstrInfo::isBundle(MCB));
83+
84+
*RelaxTarget = nullptr;
85+
MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
86+
MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
87+
// If we cannot resolve the fixup value, it requires relaxation.
88+
if (!Resolved) {
89+
switch ((unsigned)Fixup.getKind()) {
90+
case fixup_Hexagon_B22_PCREL:
91+
// GetFixupCount assumes B22 won't relax
92+
// Fallthrough
93+
default:
94+
return false;
95+
break;
96+
case fixup_Hexagon_B13_PCREL:
97+
case fixup_Hexagon_B15_PCREL:
98+
case fixup_Hexagon_B9_PCREL:
99+
case fixup_Hexagon_B7_PCREL: {
100+
if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
101+
++relaxedCnt;
102+
*RelaxTarget = &MCI;
103+
return true;
104+
} else {
105+
return false;
106+
}
107+
break;
108+
}
109+
}
110+
}
111+
bool Relaxable = isInstRelaxable(MCI);
112+
if (Relaxable == false)
113+
return false;
114+
115+
MCFixupKind Kind = Fixup.getKind();
116+
int64_t sValue = Value;
117+
int64_t maxValue;
118+
119+
switch ((unsigned)Kind) {
120+
case fixup_Hexagon_B7_PCREL:
121+
maxValue = 1 << 8;
122+
break;
123+
case fixup_Hexagon_B9_PCREL:
124+
maxValue = 1 << 10;
125+
break;
126+
case fixup_Hexagon_B15_PCREL:
127+
maxValue = 1 << 16;
128+
break;
129+
case fixup_Hexagon_B22_PCREL:
130+
maxValue = 1 << 23;
131+
break;
132+
default:
133+
maxValue = INT64_MAX;
134+
break;
135+
}
136+
137+
bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
138+
139+
if (isFarAway) {
140+
if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
141+
++relaxedCnt;
142+
*RelaxTarget = &MCI;
143+
return true;
144+
}
145+
}
146+
31147
return false;
32148
}
33149

34-
bool fixupNeedsRelaxation(MCFixup const & /*Fixup*/, uint64_t /*Value*/,
35-
MCRelaxableFragment const * /*DF*/,
36-
MCAsmLayout const & /*Layout*/) const override {
37-
llvm_unreachable("fixupNeedsRelaxation() unimplemented");
150+
/// Simple predicate for targets where !Resolved implies requiring relaxation
151+
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
152+
const MCRelaxableFragment *DF,
153+
const MCAsmLayout &Layout) const override {
154+
llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
38155
}
39156

40157
void relaxInstruction(MCInst const & /*Inst*/,

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
5656
return (MCII.get(MCI.getOpcode()));
5757
}
5858

59+
unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII,
60+
MCInst const &MCI) {
61+
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
62+
return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
63+
}
64+
65+
MCOperand const &
66+
HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,
67+
MCInst const &MCI) {
68+
unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
69+
MCOperand const &MO = MCI.getOperand(O);
70+
71+
assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
72+
HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
73+
(MO.isImm() || MO.isExpr()));
74+
return (MO);
75+
}
76+
5977
unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII,
6078
MCInst const &MCI) {
6179
const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
@@ -137,6 +155,12 @@ bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,
137155
return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
138156
}
139157

158+
MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
159+
assert(isBundle(MCB));
160+
assert(Index < HEXAGON_PACKET_SIZE);
161+
return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
162+
}
163+
140164
bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) {
141165
auto Result = Hexagon::BUNDLE == MCI.getOpcode();
142166
assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ unsigned short getCExtOpNum(MCInstrInfo const &MCII, MCInst const &MCI);
5454

5555
MCInstrDesc const &getDesc(MCInstrInfo const &MCII, MCInst const &MCI);
5656

57+
// Return the index of the extendable operand
58+
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI);
59+
60+
// Return a reference to the extendable operand
61+
MCOperand const &getExtendableOperand(MCInstrInfo const &MCII,
62+
MCInst const &MCI);
63+
5764
// Return the implicit alignment of the extendable operand
5865
unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI);
5966

@@ -83,6 +90,9 @@ unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI);
8390
// Return whether the instruction is a legal new-value producer.
8491
bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI);
8592

93+
// Return the instruction at Index
94+
MCInst const &instruction(MCInst const &MCB, size_t Index);
95+
8696
// Returns whether this MCInst is a wellformed bundle
8797
bool isBundle(MCInst const &MCI);
8898

0 commit comments

Comments
 (0)