I have some problems of getting the index of a basic block.
for (Function::iterator II = F.begin(), EE = F.end(); II != EE; ++II, ++ii)
{ BasicBlock* BB=II;
I have segfaults or cannot use complex structures of several methods that I found in LLVM. Do you know how to use as simply as possible the methods found at :
http://llvm.org/doxygen/Instructions_8h_source.html#l02136
http://llvm.org/doxygen/EdgeBundles_8cpp_source.html#l00078
Or something equivalent? I just want to get an ID of the basic blocks.
Thank you !
As Eli Bendersky pointed out in the comment above, it depends on your interpretation of index. If you are just interested in unique identifier for the basic block, basic block's name is unique in a Function. You can get that using
BB->getName()
There are other types of IDs associated with basic blocks that are dependent on the nature of your algorithm. For example, if you are writing a dominator tree construction algorithm using the iterative finger algorithm by Keith Cooper, you will associate each basic block with an incremental ID in inverse depth first order. This ID is not a part of the BasicBlock struct and should be maintained by you.
Related
I'm working with (https://github.com/ivmai/cudd) with the goal of the following repetitive process:
(1) Input: (Coherent, non-decreasing) Boolean function expression
top = a_1a_2a_3...+ x_1x_2x_3... + z_1z_2z_3...). The Booleans I'm working with have
thousands of vars (ai...zj) and hundreds of terms.
(2) Processing: Convert Boolean to a BDD to simplify the calculation of the minterms, or mutually
exclusive cut-sets (as we call them in the Reliability world).
(3) Output: Take the set of m.e. minimal cutsets (minterms). Calculate the top event probability by
adding up all the minterms found in (2).
I've found a way to do this with a labor-intensive manual C interface to build the Boolean. I've also found how to do it with the excellent tulip-dd Py interface, but unable to make it scale as with cudd.
Now I'm hoping with the C++ interface to cudd I can get the best of both worlds (Am I asking for too much?) Namely, the convenience of say tulip-dd with the scalability of cudd. So here's some sample code. Where I'm failing is in step 3, printing out the minterms, which I used to be able to do in C. How do I do it with the C++ interface?! Please see comments in the code for my specific thoughts and attempts.
int main()
{
/*DdManager* gbm; /* Global BDD manager. I suppose we do not use this if we use the Cudd type below.*/
/* (1-2) Declare the vars and build the Boolean. Convert Boolean to BDD */
Cudd mgr(0, 0);
BDD a = mgr.bddVar();
BDD b = mgr.bddVar();
BDD c = mgr.bddVar();
BDD d = mgr.bddVar();
BDD e = mgr.bddVar();
BDD top = a*(b + c + d*e);
/* How to print out the equivalent to below, which prints out all minterms and their relevant vars in C.
But the mgr below has to be a *DManager ? If so, how to convert? */
Cudd_PrintDebug(mgr, BDD, 2, 4);
return 0
}
Thanks,
Gui
The CUDD C++ classes are very little more than a wrapper around the "DdManager*" and "DdNode*" data types. They make sure that you don't accidentally forget to Cudd_Ref(..) or Cudd_RecursiveDeref(...) *DD nodes that you are using.
As such, these classes have functions that you can use to access the underlying data types. So for instance, if you want to call the "Cudd_PrintDebug" function on the "top" BDD, then you can do that with:
Cudd_PrintDebug(mgr.getManager(), top.getNode(), 2, 4);
The modification to your code was minimal.
Note that when using a plain CUDD DdNode* that you obtain with the "getNode" function, you have to make sure manually that you don't introduce node count leaks. If you use the DdNodes in a "read only fashion", only store DdNode* that correspond to BDD objects that you also store, and make sure that the BDD objects always live longer than the DdNode* pointers, this does not happen, though.
I'm only mentioning this since at some point you may want to iterate through the cubes of a BDD. These are essentially not-guaranteed-to-be-minimal minterms. There are special iterators in CUDD for this. However, if you really want the minterms, this may not be right approach. There is other software using CUDD that comes with its own functions for enumerating the minterms.
As a final note (outside of the scope of StackOverflow), you wrote that "The Booleans I'm working with have thousands of vars (ai...zj) and hundreds of terms." - There is no guarantee that using BDDs with so many variables is the way to go here. But please try it out. Having thousands of variables is often problematic for BDD-based approaches. Your application may or may not be an exception to this observation. An alternative approach may be to encode the search problem for all minterms of your original expression as an incremental satisfiability (SAT) solving problem.
I'm currently reading Nancy Lynch book about distributed systems, chapter about IO automaton. And I have following questions related to book exercise 8.13(c).
We are given some automaton A with sig(A) is empty. Traces(P) is the set of sequences over {1,2} in wich every occurance of 1 is immediatly followed by a 2. I need to show that P is neither a safety property nor a liveness property. and show explicitly that P could be expressed as intersections of S and L.
Here is my problem: I can show that P is not safety because it breaks prefix-closed property, e.g. {2,1,2} has no prefix belonging to P (it should be of the form {...,1} which is impossible for P). But I don't know how to deal with L property -- either it is empty or include trace(P) -- trace(P) $\subset$ trace(L). If it is empty then traces(P) is empty because traces(P)= traces(S) $\cap$ traces(L) which is wrong. So I think that traces(P) is subset of traces(L).
Is my conclusion related to traces(L) is right?
How can I explicitly express traces(P)=traces(S) $\cap$ traces(L) for this problem?
Thanks in advance.
I have a generic question on how to write a C++ code to solve a general class of problems. The class of problems are described in some scripting language that will be read dynamically by the c++ program. E.g. the problem can be described like the following:
syms a b c x
sol = solve(a*x^2 + b*x + c == 0)
sola = solve(a*x^2 + b*x + c == 0, a)
Here I am just using MATLAB for illustration purposes, and I am not trying to build anything like MATLAB. What I am really after is to find out how, in general, does one go about designing a C++ program that will take in a script, which describes some calculation instructions, and then read/interpret the logic described in the script and then perform the calculations as described.
The general architecture of your program will look as follows:
(from the parsing article on Wikipedia)
There are plenty of tutorials covering lexical analysis, parsing and building parse trees or, more often, abstract syntax trees (AST). See, for example, the Kaleidoscope tutorial from LLVM.
Once you constructed the AST, you'll need to translate it into some internal representation such as byte code and pass it to an interpreter or a virtual machine. In some cases it is possible to skip this step and work directly with AST.
Interpreter will take the input generated on the previous step, construct the runtime representation of the algebraic problem (which is also a tree-like data structure) and pass it to the actual solver.
The solver will analyze the structure of the problem and apply relevant methods to find the solution for the equation. For example, if x is a variable and a, b and c are parameters in your example, it can detect that it is a quadratic equation and apply well known formulas to find the solution.
I'm using Boost Spirit to implement functionality in some software that allows the user to enter a mathematical equation that will be repeatedly applied to an input stream. Input stream values are represented as symbols using boost::spirit::qi::symbols which the user can reference in their equation. (e.g. out1 = 3 * in1 + in2)
Parsing and compiling the user's equation is not performance sensitive but calculating its output value is as it forms part of a time-critical pipeline.
The standard way Spirit is used within the documentation is to calculate the output (attribute) of an input as it is parsed. However, as between each calculation only the attribute values of the symbols (out1, in1, etc.) will have changed, it feels like there might be a more efficient way to achieve this, perhaps by caching the abstract syntax tree of the expression and reiterating through it.
What is the most efficient way to recalculate the value of this (fixed) equation given a new set of symbol values?
The standard way Spirit is used is not as limited as you seem to think.
While you can use it to calulate an immediate value on the fly, it is much more usual to build an AST tree in the output attribute, that can be transformed (simplified, optimized) and interpreted (e.g. emitting virtual machine or even assembly instructions).
The compiler tutorials show this in full fledged, but the calculator samples are very close to what you seem to be looking for: http://www.boost.org/doc/libs/1_55_0/libs/spirit/example/qi/compiler_tutorial/
calc1 in example/qi/compiler_tutorial/calc1.cpp
Plain calculator example demonstrating the grammar. The parser is a syntax
checker only and does not do any semantic evaluation.
calc2 in example/qi/compiler_tutorial/calc2.cpp
A Calculator example demonstrating the grammar and semantic actions using
plain functions. The parser prints code suitable for a stack based virtual
machine.
calc3 in example/qi/compiler_tutorial/calc3.cpp
A calculator example demonstrating the grammar and semantic actions using
phoenix to do the actual expression evaluation. The parser is essentially
an "interpreter" that evaluates expressions on the fly.
Here's where it gets interesting for you, since it stops doing the calculations during parsing:
calc4 in example/qi/compiler_tutorial/calc4.cpp
A Calculator example demonstrating generation of AST. The AST, once
created, is traversed,
To print its contents and
To evaluate the result.
calc5 in example/qi/compiler_tutorial/calc5.cpp
Same as Calc4, this time, we'll incorporate debugging support, plus error
handling and reporting.
calc6 in example/qi/compiler_tutorial/calc6.cpp
Yet another calculator example! This time, we will compile to a simple
virtual machine. This is actually one of the very first Spirit example
circa 2000. Now, it's ported to Spirit2.
calc7 in example/qi/compiler_tutorial/calc7/main.cpp
Now we'll introduce variables and assignment. This time, we'll also be
renaming some of the rules -- a strategy for a grander scheme to come ;-)
This version also shows off grammar modularization. Here you will see how
expressions and statements are built as modular grammars.
calc8 in example/qi/compiler_tutorial/calc8/main.cpp
Now we'll introduce boolean expressions and control structures. Is it
obvious now what we are up to? ;-)
I'm sure you'll find lots of inspiration towards the end of the tutorial!
You can build your own tree of calculator objects which mirrors the AST. So for your example out1 = 3 * in1 + in2 the AST is:
*
3
+
in1
in2
So you'd build an object hierarchy like this:
Multiplier(
Constant(3),
Adder(
Variable(&in1),
Variable(&in2)
)
)
With classes something like:
class Result {
virtual double value() = 0;
};
class Multiplier : public Result {
Multiplier(Result* lhs, Result* rhs);
double value() { return _lhs->value() * _rhs->value(); }
}
the theory says about lex tool (I read ocamllex) it will convert a collection of regular expressions into C (OCaml) code for a DFA (actually in a NFA and also NFA2DFA). The formal definition of a DFA M is a 5 tuple M = { Q, Sigma, transition_function, q0, F}. What I found in the generated file is the following:
a record called __ocaml_lex_tables with fields from Lexing module
a recursive function
There is a mapping between the objects/structures of a DFA and the structures generated by ocamllex? I cannot 'see' it.... also I was googling for some help and I did not find any useful example.
The answer from ocamllex tool is meaningful in a DFA context e.g. 7 states, 279 transitions, table size 1158 bytes.
Is it a state transition table ? How to 'read' it ?
Thank you for any link/hint !
ocamllex is focused on speed, so it will not have explicit states visible in generated code. The theoretical representation is not always the fastest one, in practice it is usually transformed to account for constant factor speed improvements. The states are most probably represented with indexes in the generated arrays. You can think of it as mapping back assembly code to the real source code - in the general case it is not possible to do immediately because the compiler performs some optimizations and strives for the most compact and effective code, same goes for ocamllex. And the interesting question is why do you want to do that??