On May 16, 2007, at 11:42 AM, Chris Lattner wrote: >>> Yes, I think this should be the distinction between M_PREDICATED >>> (the >>> instr already has a predicate field, but may be set to 'always') vs >>> M_PREDICABLE (the instr may or may not have a predicate field, but >>> PredicateInstruction can change it into one that does). >> >> I dunno if that's the right solution. To me, whether something is >> "predicated" is a dynamic property. It's dependent on the value of >> its predicated field. > > Okay, lets put this another way. You need to know whether you *can* > predicate something, this is the isPredicable() property we were > talking about. > > Why do you need to know if something is predicated? What does that > mean? > > Does that mean it can be predicated and the predicate is not set to > always? What client do you expect for this?
Right. The only potential client is the if-converter. If anything is already predicated on a non-always predicate before if-conversion, it needs to know. You proposed having two separate properties. I think we have need one, i.e. whether something has a predicate field. Agreed? > >>> Another thing that occurred to me is that predicates have >>> implications for livevar analysis (specifically, the scavenger). >>> Consider this code: >>> >>> R3 = add [lt] ... >>> R3 = sub [ge] ... >>> >>> Note that the add is not dead. :) >> >> Yeah, this is a problematic issue. > > yes. > >> For now, I think the if-converter >> has to be a pre-emit pass. That means it will have to do some basic >> CFG xform (i.e. remove dead blocks) unless we can move branch folding >> past it. :-( > > Ick. :( :( Indeed. But I don't see any other solution unless we want to teach the scavenger all about predication. That may come one day, but not now. >>>> Come to think of it, perhaps we should not have selects if the >>>> target >>>> uses if-conversion. >>> >>> That would be very nice. Alternatively, we could have the isel >>> "know" about predicated moves and generate them? >> >> I think the right solution is to transform select's back to control >> flow. However, this requires doing the ugly hack to do the lowering >> at scheduling time, right? > > Yes. The PPC and Sparc backend (in v8 mode) both do this. > > However, why not just emit the predicated instructions from the > isel? That would be much more efficient and clean, no? I don't think so, we can't have isel / scheduler producing code that have multiple instructions targeting the same register. And I don't want to teach the if-converter about already predicated code. e.g. extern void foo(int); int t1(int a, int b) { int x = a ? b+1 : b-1; foo(x); return x; } i.e. define i32 @t1(i32 %a, i32 %b) { entry: %tmp2 = icmp eq i32 %a, 0 ; <i1> [#uses=1] %iftmp.0.0.v = select i1 %tmp2, i32 -1, i32 1 ; <i32> [#uses=1] %iftmp.0.0 = add i32 %iftmp.0.0.v, %b ; <i32> [#uses=2] tail call void @foo( i32 %iftmp.0.0 ) ret i32 %iftmp.0.0 } We currently produce: _t1: stmfd sp!, {r4, r7, lr} add r7, sp, #4 mvn r3, #0 mov r2, #1 cmp r0, #0 moveq r2, r3 add r4, r2, r1 mov r0, r4 bl L_foo$stub mov r0, r4 ldmfd sp!, {r4, r7, pc} But what we really want is _t1: stmfd sp!, {r4, r7, lr} add r7, sp, #4 cmp r0, #0 mvneq r2, #0 <== We can't produce this if we isel predicated code movne r2, #1 <== add r4, r2, r1 mov r0, r4 bl L_foo$stub mov r0, r4 ldmfd sp!, {r4, r7, pc} And then somehow turn this into: _t1: stmfd sp!, {r4, r7, lr} add r7, sp, #4 cmp r0, #0 subeq r2, r1, #1 addne r2, r1, #1 mov r0, r4 bl L_foo$stub mov r0, r4 ldmfd sp!, {r4, r7, pc} Evan > > -Chris > _______________________________________________ > llvm-commits mailing list > llvm-commits@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits