llvm.org GIT mirror llvm / 1122b45
Merging r312348: ------------------------------------------------------------------------ r312348 | matze | 2017-09-01 11:36:26 -0700 (Fri, 01 Sep 2017) | 39 lines LiveIntervalAnalysis: Fix alias regunit reserved definition A register in CodeGen can be marked as reserved: In that case we consider the register always live and do not use (or rather ignore) kill/dead/undef operand flags. LiveIntervalAnalysis however tracks liveness per register unit (not per register). We already needed adjustments for this in r292871 to deal with super/sub registers. However I did not look at aliased register there. Looking at ARM: FPSCR (regunits FPSCR, FPSCR~FPSCR_NZCV) aliases with FPSCR_NZCV (regunits FPSCR_NZCV, FPSCR~FPSCR_NZCV) hence they share a register unit (FPSCR~FPSCR_NZCV) that represents the aliased parts of the registers. This shared register unit was previously considered non-reserved, however given that we uses of the reserved FPSCR potentially violate some rules (like uses without defs) we should make FPSCR~FPSCR_NZCV reserved too and stop tracking liveness for it. This patch: - Defines a register unit as reserved when: At least for one root register, the root register and all its super registers are reserved. - Adjust LiveIntervals::computeRegUnitRange() for new reserved definition. - Add MachineRegisterInfo::isReservedRegUnit() to have a canonical way of testing. - Stop computing LiveRanges for reserved register units in HMEditor even with UpdateFlags enabled. - Skip verification of uses of reserved reg units in the machine verifier (this usually didn't happen because there would be no cached liverange but there is no guarantee for that and I would run into this case before the HMEditor tweak, so may as well fix the verifier too). Note that this should only affect ARMs FPSCR/FPSCR_NZCV registers today; aliased registers are rarely used, the only other cases are hexagons P0-P3/P3_0 and C8/USR pairs which are not mixing reserved/non-reserved registers in an alias. Differential Revision: https://reviews.llvm.org/D37356 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@314565 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 3 years ago
5 changed file(s) with 86 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
806806 return getReservedRegs().test(PhysReg);
807807 }
808808
809 /// Returns true when the given register unit is considered reserved.
810 ///
811 /// Register units are considered reserved when for at least one of their
812 /// root registers, the root register and all super registers are reserved.
813 /// This currently iterates the register hierarchy and may be slower than
814 /// expected.
815 bool isReservedRegUnit(unsigned Unit) const;
816
809817 /// isAllocatable - Returns true when PhysReg belongs to an allocatable
810818 /// register class and it hasn't been reserved.
811819 ///
268268 // may share super-registers. That's OK because createDeadDefs() is
269269 // idempotent. It is very rare for a register unit to have multiple roots, so
270270 // uniquing super-registers is probably not worthwhile.
271 bool IsReserved = true;
271 bool IsReserved = false;
272272 for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
273 bool IsRootReserved = true;
273274 for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
274275 Super.isValid(); ++Super) {
275276 unsigned Reg = *Super;
278279 // A register unit is considered reserved if all its roots and all their
279280 // super registers are reserved.
280281 if (!MRI->isReserved(Reg))
281 IsReserved = false;
282 }
283 }
282 IsRootReserved = false;
283 }
284 IsReserved |= IsRootReserved;
285 }
286 assert(IsReserved == MRI->isReservedRegUnit(Unit) &&
287 "reserved computation mismatch");
284288
285289 // Now extend LR to reach all uses.
286290 // Ignore uses of reserved registers. We only track defs of those.
923927 // kill flags. This is wasteful. Eventually, LiveVariables will strip all kill
924928 // flags, and postRA passes will use a live register utility instead.
925929 LiveRange *getRegUnitLI(unsigned Unit) {
926 if (UpdateFlags)
930 if (UpdateFlags && !MRI.isReservedRegUnit(Unit))
927931 return &LIS.getRegUnit(Unit);
928932 return LIS.getCachedRegUnit(Unit);
929933 }
600600 UpdatedCSRs.push_back(0);
601601 IsUpdatedCSRsInitialized = true;
602602 }
603
604 bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
605 const TargetRegisterInfo *TRI = getTargetRegisterInfo();
606 for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
607 bool IsRootReserved = true;
608 for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true);
609 Super.isValid(); ++Super) {
610 unsigned Reg = *Super;
611 if (!isReserved(Reg)) {
612 IsRootReserved = false;
613 break;
614 }
615 }
616 if (IsRootReserved)
617 return true;
618 }
619 return false;
620 }
13151315 // Check the cached regunit intervals.
13161316 if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
13171317 for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
1318 if (MRI->isReservedRegUnit(*Units))
1319 continue;
13181320 if (const LiveRange *LR = LiveInts->getCachedRegUnit(*Units))
13191321 checkLivenessAtUse(MO, MONum, UseIdx, *LR, *Units);
13201322 }
0 ; RUN: llc -o - %s | FileCheck %s
1 ; Make sure we do not try to compute liveness for FPSCR which in this case
2 ; is read before being written to (this is fine because becase FPSCR is
3 ; reserved).
4 target triple = "thumbv7s-apple-ios"
5
6 %struct.wibble = type { double }
7
8 @global = common global i32 0, align 4
9 @global.1 = common global i32 0, align 4
10
11 ; CHECK-LABEL: eggs:
12 ; CHECK: sub sp, #8
13 ; VMRS instruction comes before any other instruction writing FPSCR:
14 ; CHECK-NEXT: vmrs r0, fpscr
15 ; ...
16 ; CHECK: add sp, #8
17 ; CHECK: bx lr
18 define i32 @eggs(double* nocapture readnone %arg) {
19 bb:
20 %tmp = alloca %struct.wibble, align 4
21 %tmp1 = bitcast %struct.wibble* %tmp to i8*
22 %tmp2 = tail call i32 @llvm.flt.rounds()
23 %tmp3 = ptrtoint %struct.wibble* %tmp to i32
24 %tmp4 = sitofp i32 %tmp3 to double
25 %tmp5 = fmul double %tmp4, 0x0123456789ABCDEF
26 %tmp6 = fptosi double %tmp5 to i32
27 %tmp7 = fcmp une double %tmp5, 0.000000e+00
28 %tmp8 = sitofp i32 %tmp6 to double
29 %tmp9 = fcmp une double %tmp5, %tmp8
30 %tmp10 = and i1 %tmp7, %tmp9
31 %tmp11 = sext i1 %tmp10 to i32
32 %tmp12 = add nsw i32 %tmp11, %tmp6
33 store i32 %tmp12, i32* @global, align 4
34 %tmp13 = icmp ne i32 %tmp12, 0
35 %tmp14 = icmp ne i32 %tmp2, 0
36 %tmp15 = and i1 %tmp14, %tmp13
37 br i1 %tmp15, label %bb16, label %bb18
38
39 bb16: ; preds = %bb
40 %tmp17 = load i32, i32* @global.1, align 4
41 br label %bb18
42
43 bb18: ; preds = %bb16, %bb
44 ret i32 undef
45 }
46
47 declare i32 @llvm.flt.rounds()
48 declare i32 @zot(...)