diff --git a/llvm/include/llvm/CodeGen/RegisterClassInfo.h b/llvm/include/llvm/CodeGen/RegisterClassInfo.h --- a/llvm/include/llvm/CodeGen/RegisterClassInfo.h +++ b/llvm/include/llvm/CodeGen/RegisterClassInfo.h @@ -52,10 +52,9 @@ const MachineFunction *MF = nullptr; const TargetRegisterInfo *TRI = nullptr; - // Callee saved registers of last MF. Assumed to be valid until the next - // runOnFunction() call. - // Used only to determine if an update was made to CalleeSavedAliases. - const MCPhysReg *CalleeSavedRegs = nullptr; + // Callee saved registers of last MF. + // Used only to determine if an update for CalleeSavedAliases is necessary. + SmallVector LastCalleeSavedRegs; // Map register alias to the callee saved Register. SmallVector CalleeSavedAliases; diff --git a/llvm/lib/CodeGen/RegisterClassInfo.cpp b/llvm/lib/CodeGen/RegisterClassInfo.cpp --- a/llvm/lib/CodeGen/RegisterClassInfo.cpp +++ b/llvm/lib/CodeGen/RegisterClassInfo.cpp @@ -52,22 +52,39 @@ Update = true; } - // Does this MF have different CSRs? - assert(TRI && "no register info set"); + // Test if CSRs have changed from the previous function. + const MachineRegisterInfo &MRI = MF->getRegInfo(); + const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); + bool CSRChanged = true; + if (!Update) { + CSRChanged = false; + size_t LastSize = LastCalleeSavedRegs.size(); + for (unsigned I = 0;; ++I) { + if (CSR[I] == 0 || I >= LastSize) { + CSRChanged = I != LastSize; + break; + } + if (CSR[I] != LastCalleeSavedRegs[I]) { + CSRChanged = true; + break; + } + } + } // Get the callee saved registers. - const MCPhysReg *CSR = MF->getRegInfo().getCalleeSavedRegs(); - if (Update || CSR != CalleeSavedRegs) { + if (CSRChanged) { + LastCalleeSavedRegs.clear(); // Build a CSRAlias map. Every CSR alias saves the last // overlapping CSR. CalleeSavedAliases.assign(TRI->getNumRegs(), 0); - for (const MCPhysReg *I = CSR; *I; ++I) + for (const MCPhysReg *I = CSR; *I; ++I) { for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) CalleeSavedAliases[*AI] = *I; + LastCalleeSavedRegs.push_back(*I); + } Update = true; } - CalleeSavedRegs = CSR; // Even if CSR list is same, we could have had a different allocation order // if ignoreCSRForAllocationOrder is evaluated differently. diff --git a/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll b/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll --- a/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll +++ b/llvm/test/CodeGen/PowerPC/pcrel-call-linkage-leaf.ll @@ -101,7 +101,6 @@ define dso_local signext i32 @X2IsCallerSaved(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h) local_unnamed_addr { ; CHECK-ALL-LABEL: X2IsCallerSaved: ; CHECK-S: .localentry X2IsCallerSaved, 1 -; CHECK-P9-NOT: .localentry ; CHECK-ALL: # %bb.0: # %entry ; CHECK-S-NEXT: std r29, -24(r1) # 8-byte Folded Spill ; CHECK-S-NEXT: std r30, -16(r1) # 8-byte Folded Spill diff --git a/llvm/test/CodeGen/XCore/scavenging.ll b/llvm/test/CodeGen/XCore/scavenging.ll --- a/llvm/test/CodeGen/XCore/scavenging.ll +++ b/llvm/test/CodeGen/XCore/scavenging.ll @@ -55,51 +55,52 @@ ; CHECK: .section .cp.rodata.cst4,"aMc",@progbits,4 ; CHECK: .p2align 2 ; CHECK: [[ARG5:.LCPI[0-9_]+]]: -; CHECK: .long 100003 +; CHECK: .long 100002 ; CHECK: [[INDEX0:.LCPI[0-9_]+]]: -; CHECK: .long 80002 +; CHECK: .long 100004 ; CHECK: [[INDEX1:.LCPI[0-9_]+]]: -; CHECK: .long 81002 +; CHECK: .long 80002 ; CHECK: [[INDEX2:.LCPI[0-9_]+]]: -; CHECK: .long 82002 +; CHECK: .long 81002 ; CHECK: [[INDEX3:.LCPI[0-9_]+]]: -; CHECK: .long 83002 +; CHECK: .long 82002 ; CHECK: [[INDEX4:.LCPI[0-9_]+]]: +; CHECK: .long 83002 +; CHECK: [[INDEX5:.LCPI[0-9_]+]]: ; CHECK: .long 84002 ; CHECK: .text ; !FP + large frame: spill SR+SR = entsp 2 + 100000 ; CHECK-LABEL: ScavengeSlots: ; CHECK: entsp 65535 -; CHECK: extsp 34467 +; CHECK: extsp 34468 ; scavenge r11 ; CHECK: ldaw r11, sp[0] ; scavenge r4 using SR spill slot ; CHECK: stw r4, sp[1] ; CHECK: ldw r4, cp[[[ARG5]]] ; r11 used to load 5th argument -; CHECK: ldw r11, r11[r4] -; CHECK: ldaw r4, sp[0] -; scavenge r5 using SR spill slot -; CHECK: stw r5, sp[0] -; CHECK: ldw r5, cp[[[INDEX0]]] -; r4 & r5 used by InsertSPConstInst() to emit STW_l3r instruction. -; CHECK: stw r0, r4[r5] -; CHECK: ldaw r0, sp[0] -; CHECK: ldw r5, cp[[[INDEX1]]] -; CHECK: stw r1, r0[r5] +; CHECK: stw r10, r11[r4] +; CHECK: ldaw r10, sp[0] +; CHECK: ldw r11, cp[[[INDEX0]]] +; CHECK: ldw r10, r10[r11] +; CHECK: ldaw r11, sp[0] +; CHECK: ldw r4, cp[[[INDEX1]]] +; CHECK: stw r0, r11[r4] ; CHECK: ldaw r0, sp[0] -; CHECK: ldw r1, cp[[[INDEX2]]] -; CHECK: stw r2, r0[r1] +; CHECK: ldw r11, cp[[[INDEX2]]] +; CHECK: stw r1, r0[r11] ; CHECK: ldaw r0, sp[0] ; CHECK: ldw r1, cp[[[INDEX3]]] ; CHECK: stw r3, r0[r1] ; CHECK: ldaw r0, sp[0] -; CHECK: ldw r1, cp[[[INDEX4]]] -; CHECK: stw r11, r0[r1] +; CHECK: ldw r1, cp[[[INDEX5]]] +; CHECK: stw r10, r0[r1] +; CHECK: ldaw r10, sp[0] +; CHECK: ldw r0, cp[[[ARG5]]] +; CHECK: ldw r10, r10[r0] ; CHECK: ldaw sp, sp[65535] ; CHECK: ldw r4, sp[1] -; CHECK: ldw r5, sp[0] -; CHECK: retsp 34467 +; CHECK: retsp 34468 define void @ScavengeSlots(i32 %r0, i32 %r1, i32 %r2, i32 %r3, i32 %r4) nounwind { entry: %Data = alloca [100000 x i32]