Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit d7342a9

Browse files
authored
Merge pull request #59 from pftbest/msp430_backport
Backport patches for MSP430 codegen.
2 parents 3ec14da + 6041df6 commit d7342a9

File tree

4 files changed

+820
-117
lines changed

4 files changed

+820
-117
lines changed

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -3425,6 +3425,15 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
34253425
TopHalf = DAG.getSetCC(dl, getSetCCResultType(VT), TopHalf,
34263426
DAG.getConstant(0, dl, VT), ISD::SETNE);
34273427
}
3428+
3429+
// Truncate the result if SetCC returns a larger type than needed.
3430+
EVT RType = Node->getValueType(1);
3431+
if (RType.getSizeInBits() < TopHalf.getValueSizeInBits())
3432+
TopHalf = DAG.getNode(ISD::TRUNCATE, dl, RType, TopHalf);
3433+
3434+
assert(RType.getSizeInBits() == TopHalf.getValueSizeInBits() &&
3435+
"Unexpected result type for S/UMULO legalization");
3436+
34283437
Results.push_back(BottomHalf);
34293438
Results.push_back(TopHalf);
34303439
break;

lib/Target/MSP430/MSP430BranchSelector.cpp

+191-117
Original file line numberDiff line numberDiff line change
@@ -27,63 +27,84 @@ using namespace llvm;
2727

2828
#define DEBUG_TYPE "msp430-branch-select"
2929

30+
static cl::opt<bool>
31+
BranchSelectEnabled("msp430-branch-select", cl::Hidden, cl::init(true),
32+
cl::desc("Expand out of range branches"));
33+
34+
STATISTIC(NumSplit, "Number of machine basic blocks split");
3035
STATISTIC(NumExpanded, "Number of branches expanded to long format");
3136

3237
namespace {
33-
struct MSP430BSel : public MachineFunctionPass {
34-
static char ID;
35-
MSP430BSel() : MachineFunctionPass(ID) {}
38+
class MSP430BSel : public MachineFunctionPass {
3639

37-
/// BlockSizes - The sizes of the basic blocks in the function.
38-
std::vector<unsigned> BlockSizes;
40+
typedef SmallVector<int, 16> OffsetVector;
3941

40-
bool runOnMachineFunction(MachineFunction &Fn) override;
42+
MachineFunction *MF;
43+
const MSP430InstrInfo *TII;
4144

42-
MachineFunctionProperties getRequiredProperties() const override {
43-
return MachineFunctionProperties().set(
44-
MachineFunctionProperties::Property::AllVRegsAllocated);
45-
}
45+
unsigned measureFunction(OffsetVector &BlockOffsets,
46+
MachineBasicBlock *FromBB = nullptr);
47+
bool expandBranches(OffsetVector &BlockOffsets);
4648

47-
const char *getPassName() const override {
48-
return "MSP430 Branch Selector";
49-
}
50-
};
51-
char MSP430BSel::ID = 0;
49+
public:
50+
static char ID;
51+
MSP430BSel() : MachineFunctionPass(ID) {}
52+
53+
bool runOnMachineFunction(MachineFunction &MF) override;
54+
55+
MachineFunctionProperties getRequiredProperties() const override {
56+
return MachineFunctionProperties().set(
57+
MachineFunctionProperties::Property::AllVRegsAllocated);
58+
}
59+
60+
const char *getPassName() const override { return "MSP430 Branch Selector"; }
61+
};
62+
char MSP430BSel::ID = 0;
5263
}
5364

54-
/// createMSP430BranchSelectionPass - returns an instance of the Branch
55-
/// Selection Pass
56-
///
57-
FunctionPass *llvm::createMSP430BranchSelectionPass() {
58-
return new MSP430BSel();
65+
static bool isInRage(int DistanceInBytes) {
66+
// According to CC430 Family User's Guide, Section 4.5.1.3, branch
67+
// instructions have the signed 10-bit word offset field, so first we need to
68+
// convert the distance from bytes to words, then check if it fits in 10-bit
69+
// signed integer.
70+
const int WordSize = 2;
71+
72+
assert((DistanceInBytes % WordSize == 0) &&
73+
"Branch offset should be word aligned!");
74+
75+
int Words = DistanceInBytes / WordSize;
76+
return isInt<10>(Words);
5977
}
6078

61-
bool MSP430BSel::runOnMachineFunction(MachineFunction &Fn) {
62-
const MSP430InstrInfo *TII =
63-
static_cast<const MSP430InstrInfo *>(Fn.getSubtarget().getInstrInfo());
79+
/// Measure each basic block, fill the BlockOffsets, and return the size of
80+
/// the function, starting with BB
81+
unsigned MSP430BSel::measureFunction(OffsetVector &BlockOffsets,
82+
MachineBasicBlock *FromBB) {
6483
// Give the blocks of the function a dense, in-order, numbering.
65-
Fn.RenumberBlocks();
66-
BlockSizes.resize(Fn.getNumBlockIDs());
67-
68-
// Measure each MBB and compute a size for the entire function.
69-
unsigned FuncSize = 0;
70-
for (MachineBasicBlock &MBB : Fn) {
71-
unsigned BlockSize = 0;
72-
for (MachineInstr &MI : MBB)
73-
BlockSize += TII->GetInstSizeInBytes(MI);
74-
75-
BlockSizes[MBB.getNumber()] = BlockSize;
76-
FuncSize += BlockSize;
84+
MF->RenumberBlocks(FromBB);
85+
86+
MachineFunction::iterator Begin;
87+
if (FromBB == nullptr) {
88+
Begin = MF->begin();
89+
} else {
90+
Begin = FromBB->getIterator();
7791
}
7892

79-
// If the entire function is smaller than the displacement of a branch field,
80-
// we know we don't need to shrink any branches in this function. This is a
81-
// common case.
82-
if (FuncSize < (1 << 9)) {
83-
BlockSizes.clear();
84-
return false;
93+
BlockOffsets.resize(MF->getNumBlockIDs());
94+
95+
unsigned TotalSize = BlockOffsets[Begin->getNumber()];
96+
for (auto &MBB : make_range(Begin, MF->end())) {
97+
BlockOffsets[MBB.getNumber()] = TotalSize;
98+
for (MachineInstr &MI : MBB) {
99+
TotalSize += TII->GetInstSizeInBytes(MI);
100+
}
85101
}
102+
return TotalSize;
103+
}
86104

105+
/// Do expand branches and split the basic blocks if necessary.
106+
/// Returns true if made any change.
107+
bool MSP430BSel::expandBranches(OffsetVector &BlockOffsets) {
87108
// For each conditional branch, if the offset to its destination is larger
88109
// than the offset field allows, transform it into a long branch sequence
89110
// like this:
@@ -93,91 +114,144 @@ bool MSP430BSel::runOnMachineFunction(MachineFunction &Fn) {
93114
// b!CC $PC+6
94115
// b MBB
95116
//
96-
bool MadeChange = true;
97-
bool EverMadeChange = false;
98-
while (MadeChange) {
99-
// Iteratively expand branches until we reach a fixed point.
100-
MadeChange = false;
101-
102-
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
103-
++MFI) {
104-
MachineBasicBlock &MBB = *MFI;
105-
unsigned MBBStartOffset = 0;
106-
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
107-
I != E; ++I) {
108-
if ((I->getOpcode() != MSP430::JCC || I->getOperand(0).isImm()) &&
109-
I->getOpcode() != MSP430::JMP) {
110-
MBBStartOffset += TII->GetInstSizeInBytes(*I);
111-
continue;
112-
}
117+
bool MadeChange = false;
118+
for (auto MBB = MF->begin(), E = MF->end(); MBB != E; ++MBB) {
119+
unsigned MBBStartOffset = 0;
120+
for (auto MI = MBB->begin(), EE = MBB->end(); MI != EE; ++MI) {
121+
MBBStartOffset += TII->GetInstSizeInBytes(*MI);
113122

114-
// Determine the offset from the current branch to the destination
115-
// block.
116-
MachineBasicBlock *Dest = I->getOperand(0).getMBB();
117-
118-
int BranchSize;
119-
if (Dest->getNumber() <= MBB.getNumber()) {
120-
// If this is a backwards branch, the delta is the offset from the
121-
// start of this block to this branch, plus the sizes of all blocks
122-
// from this block to the dest.
123-
BranchSize = MBBStartOffset;
124-
125-
for (unsigned i = Dest->getNumber(), e = MBB.getNumber(); i != e; ++i)
126-
BranchSize += BlockSizes[i];
127-
} else {
128-
// Otherwise, add the size of the blocks between this block and the
129-
// dest to the number of bytes left in this block.
130-
BranchSize = -MBBStartOffset;
131-
132-
for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i)
133-
BranchSize += BlockSizes[i];
134-
}
123+
// If this instruction is not a short branch then skip it.
124+
if (MI->getOpcode() != MSP430::JCC && MI->getOpcode() != MSP430::JMP) {
125+
continue;
126+
}
135127

136-
// If this branch is in range, ignore it.
137-
if (isInt<10>(BranchSize)) {
138-
MBBStartOffset += 2;
139-
continue;
140-
}
128+
MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
129+
// Determine the distance from the current branch to the destination
130+
// block. MBBStartOffset already includes the size of the current branch
131+
// instruction.
132+
int BlockDistance =
133+
BlockOffsets[DestBB->getNumber()] - BlockOffsets[MBB->getNumber()];
134+
int BranchDistance = BlockDistance - MBBStartOffset;
135+
136+
// If this branch is in range, ignore it.
137+
if (isInRage(BranchDistance)) {
138+
continue;
139+
}
140+
141+
DEBUG(dbgs() << " Found a branch that needs expanding, BB#"
142+
<< DestBB->getNumber() << ", Distance " << BranchDistance
143+
<< "\n");
144+
145+
// If JCC is not the last instruction we need to split the MBB.
146+
if (MI->getOpcode() == MSP430::JCC && std::next(MI) != EE) {
147+
148+
DEBUG(dbgs() << " Found a basic block that needs to be split, BB#"
149+
<< MBB->getNumber() << "\n");
150+
151+
// Create a new basic block.
152+
MachineBasicBlock *NewBB =
153+
MF->CreateMachineBasicBlock(MBB->getBasicBlock());
154+
MF->insert(std::next(MBB), NewBB);
141155

142-
// Otherwise, we have to expand it to a long branch.
143-
unsigned NewSize;
144-
MachineInstr &OldBranch = *I;
145-
DebugLoc dl = OldBranch.getDebugLoc();
146-
147-
if (I->getOpcode() == MSP430::JMP) {
148-
NewSize = 4;
149-
} else {
150-
// The BCC operands are:
151-
// 0. MSP430 branch predicate
152-
// 1. Target MBB
153-
SmallVector<MachineOperand, 1> Cond;
154-
Cond.push_back(I->getOperand(1));
155-
156-
// Jump over the uncond branch inst (i.e. $+6) on opposite condition.
157-
TII->ReverseBranchCondition(Cond);
158-
BuildMI(MBB, I, dl, TII->get(MSP430::JCC))
159-
.addImm(4).addOperand(Cond[0]);
160-
161-
NewSize = 6;
156+
// Splice the instructions following MI over to the NewBB.
157+
NewBB->splice(NewBB->end(), &*MBB, std::next(MI), MBB->end());
158+
159+
// Update the successor lists.
160+
for (MachineBasicBlock *Succ : MBB->successors()) {
161+
if (Succ == DestBB) {
162+
continue;
163+
}
164+
MBB->replaceSuccessor(Succ, NewBB);
165+
NewBB->addSuccessor(Succ);
162166
}
163-
// Uncond branch to the real destination.
164-
I = BuildMI(MBB, I, dl, TII->get(MSP430::Bi)).addMBB(Dest);
165167

166-
// Remove the old branch from the function.
167-
OldBranch.eraseFromParent();
168+
// We introduced a new MBB so all following blocks should be numbered
169+
// and measured again.
170+
measureFunction(BlockOffsets, &*MBB);
168171

169-
// Remember that this instruction is NewSize bytes, increase the size of the
170-
// block by NewSize-2, remember to iterate.
171-
BlockSizes[MBB.getNumber()] += NewSize-2;
172-
MBBStartOffset += NewSize;
172+
++NumSplit;
173173

174-
++NumExpanded;
175-
MadeChange = true;
174+
// It may be not necessary to start all over at this point, but it's
175+
// safer do this anyway.
176+
return true;
176177
}
178+
179+
MachineInstr &OldBranch = *MI;
180+
DebugLoc dl = OldBranch.getDebugLoc();
181+
int InstrSizeDiff = -TII->GetInstSizeInBytes(OldBranch);
182+
183+
if (MI->getOpcode() == MSP430::JCC) {
184+
MachineBasicBlock *NextMBB = &*std::next(MBB);
185+
assert(MBB->isSuccessor(NextMBB) &&
186+
"This block must have a layout successor!");
187+
188+
// The BCC operands are:
189+
// 0. Target MBB
190+
// 1. MSP430 branch predicate
191+
SmallVector<MachineOperand, 1> Cond;
192+
Cond.push_back(MI->getOperand(1));
193+
194+
// Jump over the long branch on the opposite condition
195+
TII->ReverseBranchCondition(Cond);
196+
MI = BuildMI(*MBB, MI, dl, TII->get(MSP430::JCC))
197+
.addMBB(NextMBB)
198+
.addOperand(Cond[0]);
199+
InstrSizeDiff += TII->GetInstSizeInBytes(*MI);
200+
++MI;
201+
}
202+
203+
// Unconditional branch to the real destination.
204+
MI = BuildMI(*MBB, MI, dl, TII->get(MSP430::Bi)).addMBB(DestBB);
205+
InstrSizeDiff += TII->GetInstSizeInBytes(*MI);
206+
207+
// Remove the old branch from the function.
208+
OldBranch.eraseFromParent();
209+
210+
// The size of a new instruction is different from the old one, so we need
211+
// to correct all block offsets.
212+
for (int i = MBB->getNumber() + 1, e = BlockOffsets.size(); i < e; ++i) {
213+
BlockOffsets[i] += InstrSizeDiff;
214+
}
215+
MBBStartOffset += InstrSizeDiff;
216+
217+
++NumExpanded;
218+
MadeChange = true;
177219
}
178-
EverMadeChange |= MadeChange;
179220
}
221+
return MadeChange;
222+
}
223+
224+
bool MSP430BSel::runOnMachineFunction(MachineFunction &mf) {
225+
MF = &mf;
226+
TII = static_cast<const MSP430InstrInfo *>(MF->getSubtarget().getInstrInfo());
227+
228+
// If the pass is disabled, just bail early.
229+
if (!BranchSelectEnabled)
230+
return false;
231+
232+
DEBUG(dbgs() << "\n********** " << getPassName() << " **********\n");
233+
234+
// BlockOffsets - Contains the distance from the beginning of the function to
235+
// the beginning of each basic block.
236+
OffsetVector BlockOffsets;
237+
238+
unsigned FunctionSize = measureFunction(BlockOffsets);
239+
// If the entire function is smaller than the displacement of a branch field,
240+
// we know we don't need to expand any branches in this
241+
// function. This is a common case.
242+
if (isInRage(FunctionSize)) {
243+
return false;
244+
}
245+
246+
// Iteratively expand branches until we reach a fixed point.
247+
bool MadeChange = false;
248+
while (expandBranches(BlockOffsets))
249+
MadeChange = true;
250+
251+
return MadeChange;
252+
}
180253

181-
BlockSizes.clear();
182-
return true;
254+
/// Returns an instance of the Branch Selection Pass
255+
FunctionPass *llvm::createMSP430BranchSelectionPass() {
256+
return new MSP430BSel();
183257
}

0 commit comments

Comments
 (0)