aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/liveness.c
AgeCommit message (Collapse)AuthorFilesLines
2017-11-18fix support of floating-point compareLuc Van Oostenryck1-0/+1
Comparision of floating-point values can't be done like for integral values because of the possibility to have NaNs which can't be ordered with normal values or even between themselves. The real difference appears once there is any "reasoning" done with the result of the comparison. For example, once NaNs are taken in account: "!(a < b)" and "(a >= b)" are not the same. In fact the usual comparison operators must be reinterpreted as implicitely first testing if any of the operand is a Nan and return 'false' if it is the case. Thus "a < b" becomes "!isnan(a) && !isnan(b) && (a < b)". If we need to negate the comparison we get "!(a < b)" which naturally becomes "isnan(a) || isnan(b) || (a >= b)". We thus need two sets of operators for comparison of floats: one for the "ordered" values (only true if neither operand is a Nan) and one for the "values" (also true if either operand is a NaN). A negation of the comparison switch from one of the set to the other. So, introduce another set of instructions for the comparison of floats. Note: the C standard requires that: *) "x == x" is false if x is a NaN, *) "x != x" is true if x is a NaN, and this is coherent with "x != x" <-> "!(x == x)". Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
2017-03-06split OP_BR between unconditional & conditional: OP_CBRLuc Van Oostenryck1-1/+2
OP_BR instructions exist in two flavours, relatively much differentiated: conditional & non-conditional. One has an operand (and thus its usage need to be cared for, must be handled in liveness analysis, ..) the other has not; one has two BB target, the other only one. There is essentially no places in the code where both flavours are handled the same. Sometimes they both must be handled but each with their specificities but in most cases only one of them is concerned and we need to filter out the other one. In both cases it means that we need to check what kind we're dealing with. There is already a problem with this because there is several ways to test which kind an OP_BR is and they are not exactly equivalent: 1) testing if insn->cond is NULL 2) testing if one of insn->bb_true or ->bb_false is NULL. There exist also an helper (is_branch_goto()) which does the second tests but which is never used. It appears that the first test should not be used because in some cases an conditional OP_BR is changed into a non-conditional one by (amongst others things) setting it's ->cond to VOID. We should thus always use the seconds test (which need two compares with NULL). This could be corrected in several ways (like changing all the places wheer the first test is used, use the helper everywhere or never set ->cond to VOID) but the simplest is to simply split them in two separated instructions: OP_BR & OP_CBR, especailly given the fact that in most cases the OP_BR was first selected by a switch (opcode). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
2017-02-13remove unused arg in uses/defs functionsLuc Van Oostenryck1-15/+15
In the liveness analysis, the use/def methods have a 'struct instruction *' argument. This arg is never used and it's not clear for what it could be used, what it would represent. This patch remove this argument from all the concerned functions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
2017-02-13recursive phi_defines cannot happenLuc Van Oostenryck1-4/+0
The function phi_defines() does the liveness tracking of phi-pseudos (pseudos in OP_PHIs args). While doing this, the function is recursively called when the pseudo would be defined by another phi-node; but this condition is impossible because all phi-pseudos are defined by OP_PHISOURCE instructions. This patch remove the recursive call and its associated test. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
2009-08-02unssa: track uses when replacing a phi nodeKamil Dudka1-1/+1
Hello, attached are patch, testing input for test-unssa and its outputs before patch and after patch. Thanks in advance for considering the patch! Kamil test: .L0x7f9fb2030010 <entry-point> phisrc.32 %phi2(ptr) <- %arg1 br .L0x7f9fb2030130 .L0x7f9fb2030130 copy.32 %r1(ptr) <- %r5(ptr) br %r1(ptr), .L0x7f9fb2030058, .L0x7f9fb20300e8 .L0x7f9fb2030058 load.32 %r3 <- 0[%r1(ptr)] phisrc.32 %phi3(ptr) <- %r3 br .L0x7f9fb2030130 .L0x7f9fb20300e8 ret test: .L0x7f4a7f7f1010 <entry-point> copy.32 %r5(ptr) <- %arg1 br .L0x7f4a7f7f1130 .L0x7f4a7f7f1130 copy.32 %r1(ptr) <- %r5(ptr) br %r1(ptr), .L0x7f4a7f7f1058, .L0x7f4a7f7f10e8 .L0x7f4a7f7f1058 load.32 %r3 <- 0[%r1(ptr)] copy.32 %r5(ptr) <- %r3 br .L0x7f4a7f7f1130 .L0x7f4a7f7f10e8 ret >From 66a02fa7cec780fc88d6ef4cce7a1e704928808a Mon Sep 17 00:00:00 2001 From: Kamil Dudka <kdudka@redhat.com> Date: Sun, 9 Aug 2009 10:22:11 +0200 Subject: [PATCH] unssa: track uses when replacing a phi node The output of test-unssa is inconsistent for a simple test-case without this patch: static void test(void **ptr) { while (ptr) { ptr = *ptr; } } Signed-off-by: Kamil Dudka <kdudka@redhat.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
2005-11-20Remove totally bogus phi-source liveness thing.Linus Torvalds1-13/+0
Thanks to Luc Van Oostenryck for pointing out a trivial example of something that does totally the wrong thing with that code. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-04-07Add compile-time "range-check" infrastructure to sparseLinus Torvalds1-0/+4
2005-04-07Split OP_CAST into signed, unsigned and FP casts.Linus Torvalds1-0/+2
Otherwise we lose the information what the target type is (we only have the bit-size of the target).
2005-04-07Split OP_SETVAL into OP_SETVAL (fp expressions and labels) and OP_SYMADDRLinus Torvalds1-0/+4
(symbol addresses). They are pretty different. Symbol addresses have special meaning during various phases, from symbol simplification to CSE.
2005-04-07Make asm linearization not drop the constraints.Linus Torvalds1-7/+16
This also makes the OP_ASM data structures a bit more structured in order to contain all the required information.
2005-04-07Remove pseudos from liveness list when they are defined.Linus Torvalds1-0/+14
This only matters for phi-nodes, since other kinds of pseudos should never see any use before their def anyway.
2005-04-07Track phi uses in a separate pass from the liveness analysis.Linus Torvalds1-2/+13
We'll want to have the full phi user list when we do liveness.
2005-04-07PHI pseudos aren't supposed to show up on the livenessLinus Torvalds1-1/+1
tracking. Make the asserts reflect that.
2005-04-07Move remove_pseudo() to linearize.hLinus Torvalds1-5/+0
2005-04-07Oops. When updatign the liveness calculation, I forgot toLinus Torvalds1-8/+6
update the code that moves "needs" information to the parent. Now that we only add real needs to the needs list, this is much simpler.
2005-04-07Fix liveness analysis.Linus Torvalds1-10/+5
Let's not add the pseudos that the bb defines internally onto the "needs" list. Rather than removign them later, just avoid putting them there in the first place. The special cases end up being argument pseudos (which aren't really defined by the entry bb) and phi-nodes.
2005-04-07Make OP_PHISOURCE track the OP_PHI instructions that it defines.Linus Torvalds1-1/+16
This allows us to always see which pseudos are nonlocally affected by the phi source. We can only do this after the instruction flow is fixed, together with the OP_DEATHNOTE phase.
2005-04-07Teach liveness analysis about asm pseudo usage.Linus Torvalds1-0/+10
2005-04-07Track argument pseudo lifetimes too.Linus Torvalds1-14/+2
This requires that we be able to handle "uses" pseudos without a defining instruction.
2005-04-07Add pseudo death-note tracking.Linus Torvalds1-58/+124
Now that we have full pseudo usage lists, we can also add deathnotes to pseudos in the instruction stream. NOTE! We add the deathnote to _before_ the last instruction that uses that pseudo. That looks a bit strange, but it's actually what you want: when we traverse the instuctions, we want to know that the inputs are dead.
2005-04-07Walk the basic-block list in reverse order for liveness analysisLinus Torvalds1-2/+2
(this approximates depth-first) rather than in-order (~breadth first). This hugely speeds up long chains pseudo use.
2005-04-07Remove OP_SETCC, make OP_SEL bigger instead.Linus Torvalds1-6/+1
This was originally done so that "struct instruction" would be smaller, but it has since grown anyway (for the memops), so splitting OP_SEL into two instructions no longer makes sense, and makes it harder on CSE.
2005-04-07Do real flow simplification only after liveness analysis.Linus Torvalds1-1/+19
The "constant conditional" stuff in flow simplification is now handled by the trivial instruction simplification, so the only thing that remained was the conditional flow based on following constant PHI-nodes. And that one can be much more effectively done after liveness analysis, when we can decide to skip even non-empty blocks if the target we are skipping to doesn't care about this particular block.
2005-04-07After doing liveness analysis, remove purely internal defs from def list.Linus Torvalds1-0/+16
The bb register usage lists are now just the minimal set of pseudos that are relevant for parents/children.
2005-04-07Simplify trivial casts (and handle pointers specially).Linus Torvalds1-0/+1
This does trivial simplification of casting to the same typesize. HOWEVER. We split casts up into whether they cast to a dereferencable pointer type or not, and we don't simplify pointer casts. This should mean that if we ever want to do type-based alias analysis, we can still avoid casted accesses. (If we do type-based alias analysis, we'll also need to make a union access do a cast. Which we probably should do anyway).
2005-04-07Rename "register.c" into "liveness.c". That's what it does.Linus Torvalds1-0/+234