Live variable analysis , is my explanation correct? - optimization

As stackexchange have not more tags about compiler tags , so I'm posting here , this question .
A variable x is said to be live at a statement Si in a program if the following three conditions hold simultaneously :
1. There exists a statement Sj that uses x
2. There is a path from Si to Sj in the flow
graph corresponding to the program
3. The path has no intervening assignment to x
including at Si and Sj
The variables which are live both at the statement in basic block 2 and at the statement in basic block 3 of the above control flow graph are
p, s, u
r, s, u
r, u
q, v
I try to explain :
As the wikipedia says "Stated simply: a variable is live if it holds a value that may be needed in the future."
As per the definition given in question, a variable is live if it is used in future before any new assignment.
Block 2 has ‘r’ and ‘v’ both as live variables. as they are used in block 4 before any new value assinged to them. Note that variable ‘u’ is not live in block 2 as ‘u’ is assigned a new value in block 1 before it is used in block 3. Variables ‘p’, ‘s’ and ‘q’ are also not live in block 2 due to same reason.
Block 3 has only ‘r’ as live variable as every other variable is assigned a new value before use.
Another explanation given as :
Only r.
p, s and u are assigned to in 1 and there is no intermediate use of them before that. Hence p, s and u are not live in both 2 and 3.
q is assigned to in 4 and hence is not live in both 2 and 3.
v is live at 3 but not at 2.
Only r is live at both 2 and 3.
But official GATE key said both r and u.

I see two things that are probably at least part of your confusion.
First, in the list of conditions for live variables, there is no restriction stating that Si != Sj, so this makes the definitions a little imprecise in my mind.
The second is your assertion "Note that variable ‘u’ is not live in block 2 as ‘u’ is assigned a new value in block 1 before it is used in block 3."
The way I would look at this would be this:
Upon entry into block 2, before the statement v = r + u is
executed (imagine a no-op empty statement inserted as the entry to
each block, and another as the exit from the block), then both r
and u must be live, because there exists an upcoming statement
that uses both, and there is a path in the code from the entry to
that statement that contains no intermediate assignments to either.
Rather than imagining these extra empty statements, using the
original semantics of the definitions, then we're just talking about
the case where Si == Sj, because both refer to the v = r + u
statement - there is trivially a path from a statement to itself
containing no additional assignments in that sense. I find it easier
to think about it with the extra empty entry and exit statements,
though.
After the execution of v = r + u, however, at the imaginary
block exit empty statement, it is now safe to consider u as not
live (alternatively, dead), because nothing in block 4 uses it, and
it's reassigned in block 1 before it's ever used again in either
block 2 or 3.
So, part of the confusion seems to be thinking of whether a variable is live in a particular block, which doesn't really fit with the definitions - you need to think about whether a variable is live at the point of a particular statement. You could make the case that the variable u is both alive and dead in block 2, depending on whether you look at it before execution of the lone statement, or after...

Related

Verilog: Use of register: When are the values actually updated?

When exactly are the variables inside an always-block in Verilog updated?
E.g. if the reg C is changed multiple times in an always-block: does the value of it always change? Or is the value only "physically written" to the reg at the end of the always-block?
Would it be better to use an extra intermediate register which is only actualized at the end of the always-block? Would it make any difference?
reg C;
always #(*)
C = 0;
C = A;
C = 1;
C = B;
end
Other example:
If I have a module with an always block as follows, could the multiple assignments of the output exhibit sort of a glitch, where the output quickly goes to 0 before getting the value of B? Does it make a difference if I use blocking (=) or non-blocking (<=) assignments?
module example1 (output C, input A, input B);
always #(*)
begin
C = 1’b0;
if (A==1)
C = B ;
end
endmodule
Example with intermediate register to avoid unwanted change of the output.
module example1 (output C, input A, input B);
reg intermediateReg;
always #(*)
begin
intermediateReg = 1’b0;
if (A==1)
intermediateReg = B ;
end
C <= intermediateReg;
endmodule
In the examples you provided the code behaves identically to the 'c' code. The variable gets re-assigned new values and the last one wins. In verilog this is true for blocking (=) or non-blocking (<=) assignments, but not for the mix of them.
As in 'c' it is up to the compiler optimization technique. It can eliminate unneeded assignments, so only the last one is relevant.
In your first example the value of 'C' will be 'B' at the end of the block. The value of 'C' in the second example will either be 0 or B, depending on A.
Now, for the purpose of a simplicity of explanation, mixing of blocking and non-blocking assignments will cause the last 'non-blocking' assignment win. The reason is that all nba's are executed after the block is finished.
always #(*) begin
C <= A;
C = B;
end
The value of C will be A at the end of the simulation cycle.
As for the question about using intermediate values, there is no difference. You use them as needed. The simulation compiler or synthesis will optimize your code in any case. The last example is absolutely normal, except that it does not change anything at all. It behaves the same way as this, which is more explicit and more readable in my opinion. The only problem is that you incorrectly use nba assignments int combinational logic (which i fixed).
always #(*)
begin
if (A==1)
C = B ;
else
C = 1'b0;
I guess there is another silent question in your post, will the intermediate value cause events on 'C', the answer in this case is no. There will be no events produced by the always block till it finishes its execution (or till it hits a delay or starts waiting on an event). So, only the last value is relevant.
In a testbench code you can see a situation like that:
always #* begin
C = A;
C = B;
#5 C = D;
end
In the above case The value of C will become B. The execution of the always block will stop for #5 delays. During that time other blocks will see the value B. In #5 ticks, the value will be changed to D.
If you want to know what blocking and non-blocking assignments do in standard Verilog (like you would have in simulation), you can easily look that up.
If you're talking about hardware, the type of hardware you get will depend on what's in the sensitivity list, not type type of assignments you use. The type of assignment will affect the combinational logic that is synthesized from your code. Assuming you aren't doing anything unsynthesizable, the logic you get should be equivalent to what the Verilog standard specifies but won't be a 1:1 direct mapping of your code.
So, no, adding intermediates won't necessarily help with glitches in the hardware. There will be other code and timing specifications, etc. for dealing with stuff like that.

How does multiple assignment work?

From Section 4.1 of Programming in Lua.
In a multiple assignment, Lua first evaluates all values and only then
executes the assignments. Therefore, we can use a multiple assignment
to swap two values, as in
x, y = y, x -- swap x' fory'
How does the assignment work actually?
How multiple assignment gets implemented depends on what implementation of Lua you are using. The implementation is free to do things anyway it likes as long as it preserves the semantics. That is, no matter how things get implemented, you should get the same result as if you had saved all the values in the RHS before assigning them to the LHS, as the Lua book explains.
If you are still curious about the actual implementation, one thing you can do is see what is the bytecode that gets produced for a certain program. For example, taking the following program
local x,y = 10, 11
x,y = y,x
and passing it to the bytecode compiler (luac -l) for Lua 5.2 gives
main <lop.lua:0,0> (6 instructions at 0x9b36b50)
0+ params, 3 slots, 1 upvalue, 2 locals, 2 constants, 0 functions
1 [1] LOADK 0 -1 ; 10
2 [1] LOADK 1 -2 ; 11
3 [2] MOVE 2 1
4 [2] MOVE 1 0
5 [2] MOVE 0 2
6 [2] RETURN 0 1
The MOVE opcode assigns the value in the right register to the left register (see lopcodes.h in the Lua source for more details). Apparently, what is going on is that registers 0 and 1 are being used for x and y and slot 2 is being used as a temporary extra slot. x and y get initialized with constants in the first two opcodes and in the next three 3 opcodes a swap is performed using the "temporary" second slot, kind of like you would do by hand:
tmp = y -- MOVE 2 1
y = x -- MOVE 1 0
x = tmp -- MOVE 0 2
Given how Lua used a different approach when doing a swapping assignment and a static initialization, I wouldn't be surprised if you got different results for different kinds of multiple assignments (setting table fields is probably going to look very different, specially since then the order should matter due to metamethods...). We would need to find the part in the source where the bytecode gets emitted to be 100% sure though. And as I mentioned before, all of this might vary between Lua versions and implementations, specially if you look at LuaJIT vs PUC Lua.

Declarations and global reference variables for several files

My folder contains several files, which are compiled in this order: global.ml, zone.ml, abs.ml, main.ml
global.ml contains some reference variables (e.g. let g1 = ref 0) for all the files.
In zone.ml there is a declaration let f = !g1.
In abs.ml, there is g1 := 5, which will be run by main in the beginning of run-time, I consider it as an initialization of g1 given the real run-time context.
Later main will call Zone.f. Curiously, what I realize is that it takes f = 0 instead of f = 5.
Do you think this behavior is normal? If so, what should I change, to make it take the current value of !g1 into account?
PS: Maybe one solution is to make a function let f v = v in zone.ml then let main call Zone.f !g1. But I have several global reference variables as g1 in global.ml, I hope they could be valid over all the files and functions, and I don't want to get them involved in the signature of a function.
You are basically concerned with the order of evaluation of the top-level values in your modules. The order in which this happens isn't related to the order that you compile the files, but rather the order that they appear when you link the files.
If you ignore the module boundaries, if you link the files in the order you give, what you have is like this:
let g1 = ref 0
let f = !g1
let () = g1 := 5
It shouldn't be surprising that f has the value 0.
Note that your main is not necessarily the first thing that happens at runtime. Top-level values are evaluated in the order the files appear when you link them. Very commonly, main is the last top-level thing to happen (because its file is usually the last one).
(Also note that having a main at all is just a convention, presumably adopted by former C programmers like me. There's no requirement to have a function named main. OCaml just evaluates the top-level values in order.)
Edit:
It's difficult to say how to restructure your code without knowing more about it. The essence of your problem appears to be that you define f as a top-level immutable value in zone.ml but you want its value to follow g1, which is a mutable value.
The simplest suggestion would be to remove the definition of f from zone.ml and replace it everywhere in the file with !g1.
If you want to retain the name f at the top level in zone.ml, you have to redefine it as something other than an immutable value. A function is the most obvious choice:
let f () = !g1
Then you would replace uses of f in zone.ml by f () instead.

What is the language of this deterministic finite automata?

Given:
I have no idea what the accepted language is.
From looking at it you can get several end results:
1.) bb
2.) ab(a,b)
3.) bbab(a, b)
4.) bbaaa
How to write regular expression for a DFA
In any automata, the purpose of state is like memory element. A state stores some information in automate like ON-OFF fan switch.
A Deterministic-Finite-Automata(DFA) called finite automata because finite amount of memory present in the form of states. For any Regular Language(RL) a DFA is always possible.
Let's see what information stored in the DFA (refer my colorful figure).
(note: In my explanation any number means zero or more times and Λ is null symbol)
State-1: is START state and information stored in it is even number of a has been come. And ZERO b.
Regular Expression(RE) for this state is = (aa)*.
State-4: Odd number of a has been come. And ZERO b.
Regular Expression for this state is = (aa)*a.
Figure: a BLUE states = EVEN number of a, and RED states = ODD number of a has been come.
NOTICE: Once first b has been come, move can't back to state-1 and state-4.
State-5: comes after Yellow b. Yellow b means b after odd numbers of a.
Once you gets b after odd numbers of a(at state-5) every thing is acceptable because there is self a loop for (b,a) at state-5.
You can write for state-5 : Yellow-b followed-by any string of a, b that is = Yellow-b (a + b)*
State-6: Just to differentiate whether odd a or even.
State-2: comes after even a then b then any number of b. = (aa)* bb*
State-3: comes after state-2 then first a then there is a loop via state-6.
We can write for state-3 comes = state-2 a (aa)* = (aa)*bb* a (aa)*
Because in our DFA, we have three final states so language accepted by DFA is union (+ in RE) of three RL (or three RE).
So the language accepted by the DFA is corresponding to three accepting states-2,3,5, And we can write like:
State-2 + state-3 + state-5
(aa)*bb* + (aa)*bb* a (aa)* + Yellow-b (a + b)*
I forgot to explain how Yellow-b comes?
ANSWER: Yellow-b is a b after state-4 or state-3. And we can write like:
Yellow-b = ( state-4 + state-3 ) b = ( (aa)*a + (aa)*bb* a (aa)* ) b
[ANSWER]
(aa)*bb* + (aa)*bb* a (aa)* + ( (aa)*a + (aa)*bb* a (aa)* ) b (a + b)*
English Description of Language: DFA accepts union of three languages
EVEN NUMBERs OF a's, FOLLOWED BY ONE OR MORE b's,
EVEN NUMBERs OF a's, FOLLOWED BY ONE OR MORE b's, FOLLOWED BY ODD NUMBERs OF a's.
A PREFIX STRING OF a AND b WITH ODD NUMBER OF a's, FOLLOWED BY b, FOLLOWED BY ANY STRING OF a AND b AND Λ.
English Description is complex but this the only way to describe the language. You can improve it by first convert given DFA into minimized DFA then write RE and description.
Also, there is a Derivative Method to find RE from a given Transition Graph using Arden's Theorem. I have explained here how to write a regular expression for a DFA using Arden's theorem. The transition graph must first be converted into a standard form without the null-move and single start state. But I prefer to learn Theory of computation by analysis instead of using the Mathematical derivation approach.
I guess this question isn't relevant anymore :) and it's probably better to guide you through it then just stating the answer, but I think I got a basic expression that covers it (it's probably minimizable), so i'll just write it down for future searchers
(aa)*b(b)* // for stoping at 2
U
(aa)*b(b)*a(aa)* // for stoping at 3
U
(aa)*b(b)*a(aa)*b((a)*(b)*)* // for stoping at 5 via 3
U
a(aa)*b((a)*(b)*)* // for stoping at 5 via 4
The examples (1 - 4) that you give there are not the language accepted by the DFA. They are merely strings that belong to the language that the DFA accepts. Therefore, they all fall in the same language.
If you want to figure out the regular expression that defines that DFA, you will need to do something called k-path induction, and you can read up on it here.

Clearing numerical values in Mathematica

I am working on fairly large Mathematica projects and the problem arises that I have to intermittently check numerical results but want to easily revert to having all my constructs in analytical form.
The code is fairly fluid I don't want to use scoping constructs everywhere as they add work overhead. Is there an easy way for identifying and clearing all assignments that are numerical?
EDIT: I really do know that scoping is the way to do this correctly ;-). However, for my workflow I am really just looking for a dirty trick to nix all numerical assignments after the fact instead of having the foresight to put down a Block.
If your assignments are on the top level, you can use something like this:
a = 1;
b = c;
d = 3;
e = d + b;
Cases[DownValues[In],
HoldPattern[lhs_ = rhs_?NumericQ] |
HoldPattern[(lhs_ = rhs_?NumericQ;)] :> Unset[lhs],
3]
This will work if you have a sufficient history length $HistoryLength (defaults to infinity). Note however that, in the above example, e was assigned 3+c, and 3 here was not undone. So, the problem is really ambiguous in formulation, because some numbers could make it into definitions. One way to avoid this is to use SetDelayed for assignments, rather than Set.
Another alternative would be to analyze the names in say Global' context (if that is the context where your symbols live), and then say OwnValues and DownValues of the symbols, in a fashion similar to the above, and remove definitions with purely numerical r.h.s.
But IMO neither of these approaches are robust. I'd still use scoping constructs and try to isolate numerics. One possibility is to wrap you final code in Block, and assign numerical values inside this Block. This seems a much cleaner approach. The work overhead is minimal - you just have to remember which symbols you want to assign the values to. Block will automatically ensure that outside it, the symbols will have no definitions.
EDIT
Yet another possibility is to use local rules. For example, one could define rule[a] = a->1; rule[d]=d->3 instead of the assignments above. You could then apply these rules, extracting them as say
DownValues[rule][[All, 2]], whenever you want to test with some numerical arguments.
Building on Andrew Moylan's solution, one can construct a Block like function that would takes rules:
SetAttributes[BlockRules, HoldRest]
BlockRules[rules_, expr_] :=
Block ## Append[Apply[Set, Hold#rules, {2}], Unevaluated[expr]]
You can then save your numeric rules in a variable, and use BlockRules[ savedrules, code ], or even define a function that would apply a fixed set of rules, kind of like so:
In[76]:= NumericCheck =
Function[body, BlockRules[{a -> 3, b -> 2`}, body], HoldAll];
In[78]:= a + b // NumericCheck
Out[78]= 5.
EDIT In response to Timo's comment, it might be possible to use NotebookEvaluate (new in 8) to achieve the requested effect.
SetAttributes[BlockRules, HoldRest]
BlockRules[rules_, expr_] :=
Block ## Append[Apply[Set, Hold#rules, {2}], Unevaluated[expr]]
nb = CreateDocument[{ExpressionCell[
Defer[Plot[Sin[a x], {x, 0, 2 Pi}]], "Input"],
ExpressionCell[Defer[Integrate[Sin[a x^2], {x, 0, 2 Pi}]],
"Input"]}];
BlockRules[{a -> 4}, NotebookEvaluate[nb, InsertResults -> "True"];]
As the result of this evaluation you get a notebook with your commands evaluated when a was locally set to 4. In order to take it further, you would have to take the notebook
with your code, open a new notebook, evaluate Notebooks[] to identify the notebook of interest and then do :
BlockRules[variablerules,
NotebookEvaluate[NotebookPut[NotebookGet[nbobj]],
InsertResults -> "True"]]
I hope you can make this idea work.