llvm.org GIT mirror llvm / 970c019
[PowerPC] ELFv2 explicit CFI for CR fields This is a minor improvement in the ELFv2 ABI. In ELFv1, DWARF CFI would represent a saved CR word (holding CR fields CR2, CR3, and CR4) using just a single CFI record refering to CR2. In ELFv2 instead, each of the CR fields is represented by its own CFI record. The advantage is that the compiler can now chose to save just a single (or two) CR fields instead of all of them, if those are the only ones that actually need saving. That can lead to more efficient code using mf(o)crf instead of the (slow) mfcr instruction. Note that this patch does not (yet) implement this more efficient code generation, but it does implement the part that is required to be ABI compliant: creating multiple CFI records if multiple CR fields are saved. Reviewed by Hal Finkel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213492 91177308-0d34-0410-b5e6-96231b3b80d8 Ulrich Weigand 5 years ago
2 changed file(s) with 37 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
513513 // Get the ABI.
514514 bool isDarwinABI = Subtarget.isDarwinABI();
515515 bool isSVR4ABI = Subtarget.isSVR4ABI();
516 bool isELFv2ABI = Subtarget.isELFv2ABI();
516517 assert((isDarwinABI || isSVR4ABI) &&
517518 "Currently only Darwin and SVR4 ABIs are supported for PowerPC.");
518519
626627 "Prologue CR saving supported only in 64-bit mode");
627628
628629 if (!MustSaveCRs.empty()) { // will only occur for PPC64
630 // FIXME: In the ELFv2 ABI, we are not required to save all CR fields.
631 // If only one or two CR fields are clobbered, it could be more
632 // efficient to use mfocrf to selectively save just those fields.
629633 MachineInstrBuilder MIB =
630634 BuildMI(MBB, MBBI, dl, TII.get(PPC::MFCR8), TempReg);
631635 for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
794798 // For 64-bit SVR4 when we have spilled CRs, the spill location
795799 // is SP+8, not a frame-relative slot.
796800 if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {
801 // In the ELFv1 ABI, only CR2 is noted in CFI and stands in for
802 // the whole CR word. In the ELFv2 ABI, every CR that was
803 // actually saved gets its own CFI record.
804 unsigned CRReg = isELFv2ABI? Reg : (unsigned) PPC::CR2;
797805 unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
798 nullptr, MRI->getDwarfRegNum(PPC::CR2, true), 8));
806 nullptr, MRI->getDwarfRegNum(CRReg, true), 8));
799807 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
800808 .addCFIIndex(CFIIndex);
801809 continue;
0 ; RUN: llc < %s | FileCheck %s
1 target datalayout = "e-m:e-i64:64-n32:64"
2 target triple = "powerpc64le-unknown-linux-gnu"
3
4 @_ZTIi = external constant i8*
5 declare i8* @__cxa_allocate_exception(i64)
6 declare void @__cxa_throw(i8*, i8*, i8*)
7
8 define void @crsave() {
9 entry:
10 call void asm sideeffect "", "~{cr2}"()
11 call void asm sideeffect "", "~{cr3}"()
12 call void asm sideeffect "", "~{cr4}"()
13
14 %exception = call i8* @__cxa_allocate_exception(i64 4)
15 %0 = bitcast i8* %exception to i32*
16 store i32 0, i32* %0
17 call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
18 unreachable
19
20 return: ; No predecessors!
21 ret void
22 }
23 ; CHECK-LABEL: @crsave
24 ; CHECK: .cfi_offset cr2, 8
25 ; CHECK: .cfi_offset cr3, 8
26 ; CHECK: .cfi_offset cr4, 8
27