llvm.org GIT mirror llvm / 8f57667
Fix PR1390. Don't spill extra register to align the stack. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36814 91177308-0d34-0410-b5e6-96231b3b80d8 Lauro Ramos Venancio 13 years ago
2 changed file(s) with 51 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
11301130 NumGPRSpills++;
11311131 }
11321132
1133 // If stack and double are 8-byte aligned and we are spilling an odd number
1134 // of GPRs. Spill one extra callee save GPR so we won't have to pad between
1135 // the integer and double callee save areas.
1136 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
1137 if (TargetAlign == 8 && (NumGPRSpills & 1)) {
1138 if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
1139 unsigned Reg = UnspilledCS1GPRs.front();
1140 MF.setPhysRegUsed(Reg);
1141 AFI->setCSRegisterIsSpilled(Reg);
1142 if (!isReservedReg(MF, Reg))
1143 ExtraCSSpill = true;
1144 } else if (!UnspilledCS2GPRs.empty()) {
1145 unsigned Reg = UnspilledCS2GPRs.front();
1146 MF.setPhysRegUsed(Reg);
1147 AFI->setCSRegisterIsSpilled(Reg);
1148 if (!isReservedReg(MF, Reg))
1149 ExtraCSSpill = true;
1150 }
1151 }
1152
11531133 // Estimate if we might need to scavenge a register at some point in order
11541134 // to materialize a stack offset. If so, either spill one additiona
11551135 // callee-saved register or reserve a special spill slot to facilitate
11791159 if (Size >= Limit) {
11801160 // If any non-reserved CS register isn't spilled, just spill one or two
11811161 // extra. That should take care of it!
1182 unsigned NumExtras = TargetAlign / 4;
1183 SmallVector Extras;
1184 while (NumExtras && !UnspilledCS1GPRs.empty()) {
1162 unsigned Extra;
1163 while (!ExtraCSSpill && !UnspilledCS1GPRs.empty()) {
11851164 unsigned Reg = UnspilledCS1GPRs.back();
11861165 UnspilledCS1GPRs.pop_back();
11871166 if (!isReservedReg(MF, Reg)) {
1188 Extras.push_back(Reg);
1189 NumExtras--;
1167 Extra = Reg;
1168 ExtraCSSpill = true;
11901169 }
11911170 }
1192 while (NumExtras && !UnspilledCS2GPRs.empty()) {
1171 while (!ExtraCSSpill && !UnspilledCS2GPRs.empty()) {
11931172 unsigned Reg = UnspilledCS2GPRs.back();
11941173 UnspilledCS2GPRs.pop_back();
11951174 if (!isReservedReg(MF, Reg)) {
1196 Extras.push_back(Reg);
1197 NumExtras--;
1175 Extra = Reg;
1176 ExtraCSSpill = true;
11981177 }
11991178 }
1200 if (Extras.size() && NumExtras == 0) {
1201 for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
1202 MF.setPhysRegUsed(Extras[i]);
1203 AFI->setCSRegisterIsSpilled(Extras[i]);
1204 }
1179 if (ExtraCSSpill) {
1180 MF.setPhysRegUsed(Extra);
1181 AFI->setCSRegisterIsSpilled(Extra);
12051182 } else {
12061183 // Reserve a slot closest to SP or frame pointer.
12071184 const TargetRegisterClass *RC = &ARM::GPRRegClass;
12621239 ARMFunctionInfo *AFI = MF.getInfo();
12631240 bool isThumb = AFI->isThumbFunction();
12641241 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1265 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
12661242 unsigned NumBytes = MFI->getStackSize();
12671243 const std::vector &CSI = MFI->getCalleeSavedInfo();
12681244
13281304 DPRCSSize += 8;
13291305 }
13301306 }
1331
1332 if (Align == 8 && (GPRCS1Size & 7) != 0)
1333 // Pad CS1 to ensure proper alignment.
1334 GPRCS1Size += 4;
13351307
13361308 if (!isThumb) {
13371309 // Build the new SUBri to adjust SP for integer callee-save spill area 1.
0 ; RUN: llvm-as < %s | llc | not grep r11
1
2 target triple = "thumb-linux-gnueabi"
3 %struct.__sched_param = type { i32 }
4 %struct.pthread_attr_t = type { i32, i32, %struct.__sched_param, i32, i32, i32, i32, i8*, i32 }
5 @i.1882 = internal global i32 1 ; [#uses=2]
6 @.str = internal constant [14 x i8] c"Thread 1: %d\0A\00" ; <[14 x i8]*> [#uses=1]
7 @.str1 = internal constant [14 x i8] c"Thread 2: %d\0A\00" ; <[14 x i8]*> [#uses=1]
8
9 define i8* @f(i8* %a) {
10 entry:
11 %tmp1 = load i32* @i.1882 ; [#uses=1]
12 %tmp2 = add i32 %tmp1, 1 ; [#uses=2]
13 store i32 %tmp2, i32* @i.1882
14 %tmp34 = inttoptr i32 %tmp2 to i8* ; [#uses=1]
15 ret i8* %tmp34
16 }
17
18 define i32 @main() {
19 entry:
20 %t = alloca i32, align 4 ; [#uses=4]
21 %ret = alloca i32, align 4 ; [#uses=3]
22 %tmp1 = call i32 @pthread_create( i32* %t, %struct.pthread_attr_t* null, i8* (i8*)* @f, i8* null ) ; [#uses=0]
23 %tmp2 = load i32* %t ; [#uses=1]
24 %ret3 = bitcast i32* %ret to i8** ; [#uses=2]
25 %tmp4 = call i32 @pthread_join( i32 %tmp2, i8** %ret3 ) ; [#uses=0]
26 %tmp5 = load i32* %ret ; [#uses=1]
27 %tmp7 = call i32 (i8*, ...)* @printf( i8* getelementptr ([14 x i8]* @.str, i32 0, i32 0), i32 %tmp5 ) ; [#uses=0]
28 %tmp8 = call i32 @pthread_create( i32* %t, %struct.pthread_attr_t* null, i8* (i8*)* @f, i8* null ) ; [#uses=0]
29 %tmp9 = load i32* %t ; [#uses=1]
30 %tmp11 = call i32 @pthread_join( i32 %tmp9, i8** %ret3 ) ; [#uses=0]
31 %tmp12 = load i32* %ret ; [#uses=1]
32 %tmp14 = call i32 (i8*, ...)* @printf( i8* getelementptr ([14 x i8]* @.str1, i32 0, i32 0), i32 %tmp12 ) ; [#uses=0]
33 ret i32 0
34 }
35
36 declare i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)
37
38 declare i32 @pthread_join(i32, i8**)
39
40 declare i32 @printf(i8*, ...)