Skip to content

Commit 6871b23

Browse files
committed
Significantly simplify this code and make it more aggressive. Instead of having
a special case hack for X86, make the hack more general: if an incoming argument register is not used in any block other than the entry block, don't copy it to a vreg. This helps us compile code like this: %struct.foo = type { int, int, [0 x ubyte] } int %test(%struct.foo* %X) { %tmp1 = getelementptr %struct.foo* %X, int 0, uint 2, int 100 %tmp = load ubyte* %tmp1 ; <ubyte> [#uses=1] %tmp2 = cast ubyte %tmp to int ; <int> [#uses=1] ret int %tmp2 } to: _test: lbz r3, 108(r3) blr instead of: _test: lbz r2, 108(r3) or r3, r2, r2 blr The (dead) copy emitted to copy r3 into a vreg for extra-block uses was increasing the live range of r3 past the load, preventing the coallescing. This implements CodeGen/PowerPC/reg-coallesce-simple.ll llvm-svn: 24115
1 parent 6beef90 commit 6871b23

File tree

1 file changed

+50
-103
lines changed

1 file changed

+50
-103
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 50 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,6 @@ namespace llvm {
7272
/// anywhere in the function.
7373
std::map<const AllocaInst*, int> StaticAllocaMap;
7474

75-
/// BlockLocalArguments - If any arguments are only used in a single basic
76-
/// block, and if the target can access the arguments without side-effects,
77-
/// avoid emitting CopyToReg nodes for those arguments. This map keeps
78-
/// track of which arguments are local to each BB.
79-
std::multimap<BasicBlock*, std::pair<Argument*,
80-
unsigned> > BlockLocalArguments;
81-
82-
8375
unsigned MakeReg(MVT::ValueType VT) {
8476
return RegMap->createVirtualRegister(TLI.getRegClassFor(VT));
8577
}
@@ -125,17 +117,30 @@ static bool isUsedOutsideOfDefiningBlock(Instruction *I) {
125117
return false;
126118
}
127119

120+
/// isOnlyUsedInEntryBlock - If the specified argument is only used in the
121+
/// entry block, return true.
122+
static bool isOnlyUsedInEntryBlock(Argument *A) {
123+
BasicBlock *Entry = A->getParent()->begin();
124+
for (Value::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E; ++UI)
125+
if (cast<Instruction>(*UI)->getParent() != Entry)
126+
return false; // Use not in entry block.
127+
return true;
128+
}
129+
128130
FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,
129131
Function &fn, MachineFunction &mf)
130132
: TLI(tli), Fn(fn), MF(mf), RegMap(MF.getSSARegMap()) {
131133

132-
// Initialize the mapping of values to registers. This is only set up for
133-
// instruction values that are used outside of the block that defines
134-
// them.
134+
// Create a vreg for each argument register that is not dead and is used
135+
// outside of the entry block for the function.
135136
for (Function::arg_iterator AI = Fn.arg_begin(), E = Fn.arg_end();
136137
AI != E; ++AI)
137-
InitializeRegForValue(AI);
138+
if (!isOnlyUsedInEntryBlock(AI))
139+
InitializeRegForValue(AI);
138140

141+
// Initialize the mapping of values to registers. This is only set up for
142+
// instruction values that are used outside of the block that defines
143+
// them.
139144
Function::iterator BB = Fn.begin(), EB = Fn.end();
140145
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
141146
if (AllocaInst *AI = dyn_cast<AllocaInst>(I))
@@ -1072,104 +1077,45 @@ CopyValueToVirtualRegister(SelectionDAGLowering &SDL, Value *V, unsigned Reg) {
10721077
}
10731078
}
10741079

1075-
/// IsOnlyUsedInOneBasicBlock - If the specified argument is only used in a
1076-
/// single basic block, return that block. Otherwise, return a null pointer.
1077-
static BasicBlock *IsOnlyUsedInOneBasicBlock(Argument *A) {
1078-
if (A->use_empty()) return 0;
1079-
BasicBlock *BB = cast<Instruction>(A->use_back())->getParent();
1080-
for (Argument::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E;
1081-
++UI)
1082-
if (isa<PHINode>(*UI) || cast<Instruction>(*UI)->getParent() != BB)
1083-
return 0; // Disagreement among the users?
1084-
1085-
// Okay, there is a single BB user. Only permit this optimization if this is
1086-
// the entry block, otherwise, we might sink argument loads into loops and
1087-
// stuff. Later, when we have global instruction selection, this won't be an
1088-
// issue clearly.
1089-
if (BB == BB->getParent()->begin())
1090-
return BB;
1091-
return 0;
1092-
}
1093-
10941080
void SelectionDAGISel::
10951081
LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL,
10961082
std::vector<SDOperand> &UnorderedChains) {
10971083
// If this is the entry block, emit arguments.
10981084
Function &F = *BB->getParent();
10991085
FunctionLoweringInfo &FuncInfo = SDL.FuncInfo;
1100-
1101-
if (BB == &F.front()) {
1102-
SDOperand OldRoot = SDL.DAG.getRoot();
1103-
1104-
std::vector<SDOperand> Args = TLI.LowerArguments(F, SDL.DAG);
1105-
1106-
// If there were side effects accessing the argument list, do not do
1107-
// anything special.
1108-
if (OldRoot != SDL.DAG.getRoot()) {
1109-
unsigned a = 0;
1110-
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
1111-
AI != E; ++AI,++a)
1112-
if (!AI->use_empty()) {
1113-
SDL.setValue(AI, Args[a]);
1114-
1115-
SDOperand Copy =
1116-
CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]);
1117-
UnorderedChains.push_back(Copy);
1118-
}
1119-
} else {
1120-
// Otherwise, if any argument is only accessed in a single basic block,
1121-
// emit that argument only to that basic block.
1122-
unsigned a = 0;
1123-
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
1124-
AI != E; ++AI,++a)
1125-
if (!AI->use_empty()) {
1126-
if (BasicBlock *BBU = IsOnlyUsedInOneBasicBlock(AI)) {
1127-
FuncInfo.BlockLocalArguments.insert(std::make_pair(BBU,
1128-
std::make_pair(AI, a)));
1129-
} else {
1130-
SDL.setValue(AI, Args[a]);
1131-
SDOperand Copy =
1132-
CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]);
1133-
UnorderedChains.push_back(Copy);
1134-
}
1135-
}
1136-
}
1137-
1138-
// Next, if the function has live ins that need to be copied into vregs,
1139-
// emit the copies now, into the top of the block.
1140-
MachineFunction &MF = SDL.DAG.getMachineFunction();
1141-
if (MF.livein_begin() != MF.livein_end()) {
1142-
SSARegMap *RegMap = MF.getSSARegMap();
1143-
const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo();
1144-
for (MachineFunction::livein_iterator LI = MF.livein_begin(),
1145-
E = MF.livein_end(); LI != E; ++LI)
1146-
if (LI->second)
1147-
MRI.copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second,
1148-
LI->first, RegMap->getRegClass(LI->second));
1149-
}
1086+
SDOperand OldRoot = SDL.DAG.getRoot();
1087+
std::vector<SDOperand> Args = TLI.LowerArguments(F, SDL.DAG);
1088+
1089+
unsigned a = 0;
1090+
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
1091+
AI != E; ++AI, ++a)
1092+
if (!AI->use_empty()) {
1093+
SDL.setValue(AI, Args[a]);
11501094

1151-
// Finally, if the target has anything special to do, allow it to do so.
1152-
EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
1153-
}
1154-
1155-
// See if there are any block-local arguments that need to be emitted in this
1156-
// block.
1157-
1158-
if (!FuncInfo.BlockLocalArguments.empty()) {
1159-
std::multimap<BasicBlock*, std::pair<Argument*, unsigned> >::iterator BLAI =
1160-
FuncInfo.BlockLocalArguments.lower_bound(BB);
1161-
if (BLAI != FuncInfo.BlockLocalArguments.end() && BLAI->first == BB) {
1162-
// Lower the arguments into this block.
1163-
std::vector<SDOperand> Args = TLI.LowerArguments(F, SDL.DAG);
1164-
1165-
// Set up the value mapping for the local arguments.
1166-
for (; BLAI != FuncInfo.BlockLocalArguments.end() && BLAI->first == BB;
1167-
++BLAI)
1168-
SDL.setValue(BLAI->second.first, Args[BLAI->second.second]);
1169-
1170-
// Any dead arguments will just be ignored here.
1095+
// If this argument is live outside of the entry block, insert a copy from
1096+
// whereever we got it to the vreg that other BB's will reference it as.
1097+
if (FuncInfo.ValueMap.count(AI)) {
1098+
SDOperand Copy =
1099+
CopyValueToVirtualRegister(SDL, AI, FuncInfo.ValueMap[AI]);
1100+
UnorderedChains.push_back(Copy);
1101+
}
11711102
}
1103+
1104+
// Next, if the function has live ins that need to be copied into vregs,
1105+
// emit the copies now, into the top of the block.
1106+
MachineFunction &MF = SDL.DAG.getMachineFunction();
1107+
if (MF.livein_begin() != MF.livein_end()) {
1108+
SSARegMap *RegMap = MF.getSSARegMap();
1109+
const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo();
1110+
for (MachineFunction::livein_iterator LI = MF.livein_begin(),
1111+
E = MF.livein_end(); LI != E; ++LI)
1112+
if (LI->second)
1113+
MRI.copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second,
1114+
LI->first, RegMap->getRegClass(LI->second));
11721115
}
1116+
1117+
// Finally, if the target has anything special to do, allow it to do so.
1118+
EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction());
11731119
}
11741120

11751121

@@ -1180,8 +1126,9 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
11801126

11811127
std::vector<SDOperand> UnorderedChains;
11821128

1183-
// Lower any arguments needed in this block.
1184-
LowerArguments(LLVMBB, SDL, UnorderedChains);
1129+
// Lower any arguments needed in this block if this is the entry block.
1130+
if (LLVMBB == &LLVMBB->getParent()->front())
1131+
LowerArguments(LLVMBB, SDL, UnorderedChains);
11851132

11861133
BB = FuncInfo.MBBMap[LLVMBB];
11871134
SDL.setCurrentBasicBlock(BB);

0 commit comments

Comments
 (0)