mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 06:09:05 +00:00
Consider subregs when calling MI::registerDefIsDead for phys deps
The scheduling dependency graph is built bottom-up within each scheduling region, and ScheduleDAGInstrs::addPhysRegDeps is called to add output/anti dependencies, based on physical registers, to the SUs for instructions based on those that come before them. In the test case, we start before post-RA scheduling with a block that looks like this: ... INLINEASM <... andc $0,$0,$2 stdcx. $0,0,$3 bne- 1b > [sideeffect] [mayload] [maystore] [attdialect], $0:[regdef-ec:G8RC], %X6<earlyclobber,def,dead>, $1:[mem], %X3<kill>, $2:[reguse:G8RC], %X5<kill>, $3:[reguse:G8RC], %X3, $4:[mem], %X3, $5:[clobber], %CC<earlyclobber,imp-def,dead>, <<badref>> ... %X4<def,dead> = ANDIo8 %X4<kill>, 1, %CR0<imp-def,dead>, %CR0GT<imp-def> ... %R29<def> = ISEL %R3<undef>, %R4<kill>, %CR0GT<kill> where it is relevant that %CC is an alias to %CR0, and that %CR0GT is a subregister of %CR0. However, for post-RA scheduling, no dependency was added to prevent the INLINEASM from being scheduled in between the ANDIo8 and the ISEL (which communicate via the %CR0GT register). In ScheduleDAGInstrs::addPhysRegDeps, when called for the %CC operand, we'd iterate over all of its aliases (which include %CC itself and also %CR0), and look for previously-encountered defs of those registers. We'd find the ANDIo8, but decide not to add a dependency between the INLINEASM and the ANDIo8 because both the INLINEASM's def of %CC is dead, and also the ANDIo8 def of %CR0 is dead. This ignores, however, that ANDIo8 has a non-dead def of %CR0GT, a subregister of %CR0, and thus a dependency still must exist. To fix this problem, when calling registerDefIsDead on the SU with the def, we also check all subregisters for possible non-dead defs, and add the dependency if any are found. Fixes PR21742. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223440 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
afcbfb40fb
commit
d281f1443a
@ -310,9 +310,15 @@ void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
|
||||
SUnit *DefSU = I->SU;
|
||||
if (DefSU == &ExitSU)
|
||||
continue;
|
||||
auto IsDefDead = [this](SUnit *DefSU, unsigned Reg) {
|
||||
for (MCSubRegIterator SR(Reg, TRI, true); SR.isValid(); ++SR)
|
||||
if (!DefSU->getInstr()->registerDefIsDead(*SR))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
if (DefSU != SU &&
|
||||
(Kind != SDep::Output || !MO.isDead() ||
|
||||
!DefSU->getInstr()->registerDefIsDead(*Alias))) {
|
||||
!IsDefDead(DefSU, *Alias))) {
|
||||
if (Kind == SDep::Anti)
|
||||
DefSU->addPred(SDep(SU, Kind, /*Reg=*/*Alias));
|
||||
else {
|
||||
|
168
test/CodeGen/PowerPC/subreg-postra.ll
Normal file
168
test/CodeGen/PowerPC/subreg-postra.ll
Normal file
@ -0,0 +1,168 @@
|
||||
; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
|
||||
target datalayout = "E-m:e-i64:64-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @jbd2_journal_commit_transaction(i32* %journal) #0 {
|
||||
entry:
|
||||
br i1 undef, label %do.body, label %if.then5
|
||||
|
||||
if.then5: ; preds = %entry
|
||||
unreachable
|
||||
|
||||
do.body: ; preds = %entry
|
||||
br i1 undef, label %do.body.i, label %trace_jbd2_start_commit.exit
|
||||
|
||||
do.body.i: ; preds = %do.body
|
||||
unreachable
|
||||
|
||||
trace_jbd2_start_commit.exit: ; preds = %do.body
|
||||
br i1 undef, label %do.body.i1116, label %trace_jbd2_commit_locking.exit
|
||||
|
||||
do.body.i1116: ; preds = %trace_jbd2_start_commit.exit
|
||||
br i1 undef, label %if.end.i1123, label %do.body5.i1122
|
||||
|
||||
do.body5.i1122: ; preds = %do.body.i1116
|
||||
unreachable
|
||||
|
||||
if.end.i1123: ; preds = %do.body.i1116
|
||||
br label %trace_jbd2_commit_locking.exit
|
||||
|
||||
trace_jbd2_commit_locking.exit: ; preds = %if.end.i1123, %trace_jbd2_start_commit.exit
|
||||
br i1 undef, label %spin_unlock.exit1146, label %if.then.i.i.i.i1144
|
||||
|
||||
if.then.i.i.i.i1144: ; preds = %trace_jbd2_commit_locking.exit
|
||||
unreachable
|
||||
|
||||
spin_unlock.exit1146: ; preds = %trace_jbd2_commit_locking.exit
|
||||
br i1 undef, label %spin_unlock.exit1154, label %if.then.i.i.i.i1152
|
||||
|
||||
if.then.i.i.i.i1152: ; preds = %spin_unlock.exit1146
|
||||
br label %spin_unlock.exit1154
|
||||
|
||||
spin_unlock.exit1154: ; preds = %if.then.i.i.i.i1152, %spin_unlock.exit1146
|
||||
br i1 undef, label %do.body.i1159, label %trace_jbd2_commit_flushing.exit
|
||||
|
||||
do.body.i1159: ; preds = %spin_unlock.exit1154
|
||||
unreachable
|
||||
|
||||
trace_jbd2_commit_flushing.exit: ; preds = %spin_unlock.exit1154
|
||||
br i1 undef, label %for.end.i, label %for.body.lr.ph.i
|
||||
|
||||
for.body.lr.ph.i: ; preds = %trace_jbd2_commit_flushing.exit
|
||||
br i1 undef, label %spin_unlock.exit.i, label %if.then.i.i.i.i.i
|
||||
|
||||
if.then.i.i.i.i.i: ; preds = %for.body.lr.ph.i
|
||||
unreachable
|
||||
|
||||
spin_unlock.exit.i: ; preds = %for.body.lr.ph.i
|
||||
unreachable
|
||||
|
||||
for.end.i: ; preds = %trace_jbd2_commit_flushing.exit
|
||||
br i1 undef, label %journal_submit_data_buffers.exit, label %if.then.i.i.i.i31.i
|
||||
|
||||
if.then.i.i.i.i31.i: ; preds = %for.end.i
|
||||
unreachable
|
||||
|
||||
journal_submit_data_buffers.exit: ; preds = %for.end.i
|
||||
br i1 undef, label %if.end103, label %if.then102
|
||||
|
||||
if.then102: ; preds = %journal_submit_data_buffers.exit
|
||||
unreachable
|
||||
|
||||
if.end103: ; preds = %journal_submit_data_buffers.exit
|
||||
br i1 undef, label %do.body.i1182, label %trace_jbd2_commit_logging.exit
|
||||
|
||||
do.body.i1182: ; preds = %if.end103
|
||||
unreachable
|
||||
|
||||
trace_jbd2_commit_logging.exit: ; preds = %if.end103
|
||||
br i1 undef, label %for.end.i1287, label %for.body.i1277
|
||||
|
||||
for.body.i1277: ; preds = %trace_jbd2_commit_logging.exit
|
||||
unreachable
|
||||
|
||||
for.end.i1287: ; preds = %trace_jbd2_commit_logging.exit
|
||||
br i1 undef, label %journal_finish_inode_data_buffers.exit, label %if.then.i.i.i.i84.i
|
||||
|
||||
if.then.i.i.i.i84.i: ; preds = %for.end.i1287
|
||||
unreachable
|
||||
|
||||
journal_finish_inode_data_buffers.exit: ; preds = %for.end.i1287
|
||||
br i1 undef, label %if.end256, label %if.then249
|
||||
|
||||
if.then249: ; preds = %journal_finish_inode_data_buffers.exit
|
||||
unreachable
|
||||
|
||||
if.end256: ; preds = %journal_finish_inode_data_buffers.exit
|
||||
br i1 undef, label %do.body277, label %if.then260
|
||||
|
||||
if.then260: ; preds = %if.end256
|
||||
br label %do.body277
|
||||
|
||||
do.body277: ; preds = %if.then260, %if.end256
|
||||
br label %while.body318
|
||||
|
||||
while.body318: ; preds = %wait_on_buffer.exit, %do.body277
|
||||
%tobool.i1295 = icmp eq i64 undef, 0
|
||||
br i1 %tobool.i1295, label %wait_on_buffer.exit, label %if.then.i1296
|
||||
|
||||
if.then.i1296: ; preds = %while.body318
|
||||
unreachable
|
||||
|
||||
wait_on_buffer.exit: ; preds = %while.body318
|
||||
br i1 undef, label %do.body378, label %while.body318
|
||||
|
||||
do.body378: ; preds = %wait_on_buffer.exit
|
||||
br i1 undef, label %while.end418, label %while.body392.lr.ph
|
||||
|
||||
while.body392.lr.ph: ; preds = %do.body378
|
||||
br label %while.body392
|
||||
|
||||
while.body392: ; preds = %wait_on_buffer.exit1319, %while.body392.lr.ph
|
||||
%0 = load i8** undef, align 8
|
||||
%add.ptr399 = getelementptr inbounds i8* %0, i64 -72
|
||||
%b_state.i.i1314 = bitcast i8* %add.ptr399 to i64*
|
||||
%tobool.i1316 = icmp eq i64 undef, 0
|
||||
br i1 %tobool.i1316, label %wait_on_buffer.exit1319, label %if.then.i1317
|
||||
|
||||
if.then.i1317: ; preds = %while.body392
|
||||
unreachable
|
||||
|
||||
wait_on_buffer.exit1319: ; preds = %while.body392
|
||||
%1 = load volatile i64* %b_state.i.i1314, align 8
|
||||
%conv.i.i1322 = and i64 %1, 1
|
||||
%lnot404 = icmp eq i64 %conv.i.i1322, 0
|
||||
%.err.4 = select i1 %lnot404, i32 -5, i32 undef
|
||||
%2 = call i64 asm sideeffect "1:.long 0x7c0000a8 $| ((($0) & 0x1f) << 21) $| (((0) & 0x1f) << 16) $| ((($3) & 0x1f) << 11) $| (((0) & 0x1) << 0) \0Aandc $0,$0,$2\0Astdcx. $0,0,$3\0Abne- 1b\0A", "=&r,=*m,r,r,*m,~{cc},~{memory}"(i64* %b_state.i.i1314, i64 262144, i64* %b_state.i.i1314, i64* %b_state.i.i1314) #1
|
||||
%prev.i.i.i1325 = getelementptr inbounds i8* %0, i64 8
|
||||
%3 = load i32** null, align 8
|
||||
store i32* %3, i32** undef, align 8
|
||||
call void @__brelse(i32* undef) #1
|
||||
br i1 undef, label %while.end418, label %while.body392
|
||||
|
||||
; CHECK-LABEL: @jbd2_journal_commit_transaction
|
||||
; CHECK-NOT: andi.
|
||||
; CHECK: stdcx.
|
||||
; CHECK: andi.
|
||||
; CHECK: isel
|
||||
|
||||
while.end418: ; preds = %wait_on_buffer.exit1319, %do.body378
|
||||
%err.4.lcssa = phi i32 [ undef, %do.body378 ], [ %.err.4, %wait_on_buffer.exit1319 ]
|
||||
br i1 undef, label %if.end421, label %if.then420
|
||||
|
||||
if.then420: ; preds = %while.end418
|
||||
call void @jbd2_journal_abort(i32* %journal, i32 signext %err.4.lcssa) #1
|
||||
br label %if.end421
|
||||
|
||||
if.end421: ; preds = %if.then420, %while.end418
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @jbd2_journal_abort(i32*, i32 signext)
|
||||
|
||||
declare void @__brelse(i32*)
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
attributes #1 = { nounwind }
|
||||
|
Loading…
Reference in New Issue
Block a user