llvm 4.0.0 Initialize an AliasSetTracker class - llvm

I'm trying to use the AliasSetTracker to collect the alias set. However, the new version makes me confused. To initialize an AliasSetTracker, I need an instance of AliasAnalysis. But the old one:
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
AliasSetTracker tr(AA);
doesn't work and the errors:
In file included from /Users/.../LLVM/llvm/include/llvm/Pass.h:388:
/Users/.../llvm/include/llvm/PassAnalysisSupport.h:223:53: error: no member
named 'ID' in 'llvm::AAResults'
return getAnalysisID<AnalysisType>(&AnalysisType::ID);
/Users.../program/Analysis.cpp:215:25: note: in
instantiation of function template specialization
'llvm::Pass::getAnalysis<llvm::AAResults>' requested here
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();

in this new version of LLVM you have to use the function getAnalysisUsage and modify the way you used the function getAnalysis :
1- Add the following function in your pass struct :
virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AAResultsWrapperPass>();
}
2- Modify your call to the getAnalysis function:
AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
It will work now :)

Related

How to run the Function Pass before the Module Pass in LLVM?

I'm implementing several Passes on the LLVM in order to add original optimization,
These Passes are based on FunctionPass and ModulePass.
Now, each Pass is invoked by corresponding opt command option which is
registerd by RegisterPass template.
In future, I'd like to these Passes to be invoked only by one opt command option.
My idea is as follows:
First, Function passes to run, and finally Module pass to run.
Each Function passes to use the former Function passes' analysis information.
The final Module pass to construct a new function using the former Function passes' result.
All of these Passes sequence to invoke by only one opt command option specifying the final Module pass.
I thought I could make it with addRequired method in the AnalysisUsage class.
However, it doesn't seem to work:
In the Function pass, several Function passes may be addRequired in the order.
In the Function pass, only one Module pass may be addRequired.
In the Function pass(X), Function pass and Module pass cannot be addRequired simultaneously.
i.e. opt command execution with option X causes to a lock status.
In the Module pass, only one Module pass may be addRequired.
In the Module pass(Y), Function pass(Z) cannot be addRequired.
i.e. opt command with option Y executes only Y, and Function pass(Z) is ignored.
I am not familiar to the Pass manager mechanism.
Anybody help me how to run the Function pass before the Module pass with only one opt command option?
The case of execution is shown below:-
$ opt -stats -load ~/samples/tryPass4.so -MPass4 hello2.ll -S -o tryPass4.ll -debug-pass=Structure
Pass Arguments: -targetlibinfo -datalayout -notti -basictti -x86tti -MPass4 -verify -verify-di -print-module
Target Library Information ↑
Data Layout                              -FPass4 doesn't appear here
No target information
Target independent code generator's TTI
X86 Target Transform Info
ModulePass Manager
Module Pass
Unnamed pass: implement Pass::getPassName()
FunctionPass Manager
Module Verifier
Debug Info Verifier
Print module to stderr
Pass Arguments: -FPass4    <- here -FPass4 appears, but not executed
FunctionPass Manager
Function Pass
***** Module Name : hello2.ll <- output from the Module pass
The source code for above is as follows:-
using namespace llvm;
namespace{
class tryFPass4 : public FunctionPass {
public :
static char ID;
tryFPass4() : FunctionPass(ID){}
~tryFPass4(){}
virtual bool runOnFunction(llvm::Function &F);
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const;
};
class tryMPass4 : public ModulePass {
public :
static char ID;
tryMPass4() : ModulePass(ID){}
~tryMPass4(){}
virtual bool runOnModule(llvm::Module &M);
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const;
};
}
bool tryFPass4::runOnFunction(Function &F) {
bool change = false;
....
return change;
}
bool tryMPass4::runOnModule(Module &M) {
bool change = false ;
....
return change;
}
void tryFPass4::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
void tryMPass4::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<tryFPass4>();
}
char tryFPass4::ID = 0;
static RegisterPass<tryFPass4> X("FPass4", "Function Pass", false, false);
char tryMPass4::ID = 0;
static RegisterPass<tryMPass4> Y("MPass4", "Module Pass", false, false);
I tried to simulate the problem here using LLVM 3.8.1.
I believe your Function pass gets to run here:
Module Pass
Unnamed pass: implement Pass::getPassName()
I do not know why it is marked as unnamed although getPassName is overriden.
A fine detail that you need to watch is that in order for the function pass to actually execute its runOnFunction method, you need to invoke the Function & specific method of getAnalysis as in:
getAnalysis<tryFPass4>(f); // where f is the current Function operating on
It seems if the dependent pass operates on a small unit of IR than the pass that requires it, it needs to be executed explicitly. I might be mistaken since I have not yet tried it with a BasicBlockPass required by a FunctionPass.

Initialization of std::function does not evaluate to a function taking 3 arguments

GameObject class .h + .cpp:
typedef std::function<void(GameObject* triggerobject, GameObject* otherobject, TriggerAction action)> PhysicsCallback;
void GameObject::OnTrigger(GameObject* triggerobject, GameObject* otherobject, TriggerAction action)
{
if (m_OnTriggerCallback)
m_OnTriggerCallback(triggerobject, otherobject, action);
}
void GameObject::SetOnTriggerCallBack(PhysicsCallback callback)
{
m_OnTriggerCallback = callback;
}
Other class:
m_pSphere->SetOnTriggerCallBack(*pCbObj);
m_pSphere->OnTrigger(m_pWallLeft, m_pSphere, GameObject::TriggerAction(0));
I figured to use the OnTrigger() function I had to set m_OnTriggerCallback. When I tried to pass corresponding arguments however I got really stuck. It seems almost impossible to initalize PhysicsCallback without getting compiler errors.
I tried:
std::function<void(GameObject* triggerobject, GameObject* otherobject, GameObject::TriggerAction action)> *obj;
*obj = (m_pWallRight, m_pSphere, GameObject::TriggerAction(0));
But no luck. *obj doesn't accept any arguments. These following lines give the same errors:
GameObject::PhysicsCallback *pCbObj; = new GameObject::PhysicsCallback(new std::function<void()>()); //term does not evaluate to a function taking 3 arguments
GameObject::PhysicsCallback *pCbObj = new GameObject::PhysicsCallback((m_pWallRight, m_pSphere, GameObject::TriggerAction(0)));
And this line *pCbObj = GameObject::PhysicsCallback(m_pWallRight, m_pSphere, GameObject::TriggerAction(0));gives this intellisense error:
http://puu.sh/gi29n/95f0f7855b.png
I'm really confused, how to use the SetOnTriggerCallBack function?
Doing
m_pSphere->OnTrigger(m_pWallLeft, m_pSphere, GameObject::TriggerAction(0));
is actually calling GameObject::TriggerAction with 0 as argument. Then, it passes its result.
What is GameObject::TriggerAction? Is it a static method ? It should be because, otherwise, you have either to std::bind it to an object instance or to apply it directly.
With a lambda I was able to create an parameter that was acceptable for the compiler:
GameObject::PhysicsCallback trigger = [=](GameObject* triggerobject, GameObject* otherobject, GameObject::TriggerAction action){};

Accessing a C++ function from a CXX test

I'm writing a few CXX unit tests for a class I have written. I have never written CXX tests before (also this is the only framework I can use). I am trying to call a function contained within my class so that I can test the output is what is expected, but I am unsure if you can do this, and if so, how.
Test.h:
class Test..... {
public:
std::string GenerateHash(const std::string& user, const std::string& url) const;
...
}
Test.cpp:
string
Test::GenerateHash(const string& user, const string& urrl) const {
...
}
I have included the header file in the CXX test, but cannot access the GenerateHash function.
Test.cxx_h:
void testCheckHashGeneration( void ) {
TS_ASSERT_EQUALS (GenerateHash("testuser", "http://www.stackoverflow.com"), "DFEGEC.....");
}
Error: error: âGenerateHashâ was not declared in this scope
I also tried:
Test.cxx_h:
void testCheckHashGeneration( void ) {
Test test;
TS_ASSERT_EQUALS (test->GenerateHash("testuser", "http://www.stackoverflow.com"), "DFEGEC.....");
}
Error: error: âTestâ has not been declared
Any help will be greatly appreciated.
In the first case, you're trying to call a member function without an instance of Test. You need a Test to call it on, as you've done in the second case.
In the second case, you're trying to call a member using the syntax for having a pointer to the object, '->', when you actually have an object. You want the second to look like this:
test.GenerateHash(...)
If you somehow had a Test*, then you could call it like
test->GenerateHash(...)
use . for objects, -> for pointers to objects.
More code and error output would be helpful.
If the GenerateHash function can be a static method, then make it static. Then call it using Test::GenerateHash(/*your arguments*/);
Considering the way you initially attempted to call GenerateHash, I would guess that this should be a static method. If its execution does not depend on a particular instance of the Test class, then it can be static.
Otherwise, use test.GenerateHash rather than test->GenerateHash

C++11 Lambda Functions inside member methods inherit scope

I've written a function foreach that accepts a lambda function ala:
void foreach(void (*p)(pNode))
{ /* ... */ }
Which works as intended if I pass a lambda function from the main loop:
int a = 5;
env.N().foreach
(
[&](pNode n)->void
{
n->tps(a);
}
);
However, if I try to call the same function from within a member method, the lambda function "inherits" the scope of the member function and generates a compiler error. For example, if I try to include it inside the member method of class Object named method(), I get the following error:
error: no matching function for call to ‘IDSet<Node>::foreach(Object::method()::<lambda(pNode)>)’
note: candidate is: void IDSet<T>::foreach(void (*)(IDSet<T>::pT)) [with T = Node, IDSet<T>::pT = pNode]
I realize this is the compiler being safe, since I could include instance-specific variables inside the lambda function, in which case the lambda would need to be scoped, however I'm wondering if it's possible to make this lambda "static".
I've tried a reinterpret_cast, however that gives me this error:
error: invalid cast from type ‘Object::method()::<lambda(pNode)>’ to type ‘void (*)(pNode)’
Specifying static before [&](pNode ... doesn't seem like valid syntax either.
Desperately, I also tried changing [&] to [=], [], [a], none of which worked.
Does anyone know if there is a way to do accomplish my goal of creating a "static" lambda function, or at any sort of lambda function that will be accepted for that matter?
Thanks!
Answer:
With help from Cat Plus Plus, I was able to turn my incorrect code:
void foreach(void (*p)(pT))
{
for(pTiter i = _map.begin(); i != _map.end(); i++)
{
(*p)(i->second);
}
}
into fully functional code:
void foreach(std::function<void(pT)>(p))
{
for(pTiter i = _map.begin(); i != _map.end(); i++)
{
p(i->second);
}
}
that does what I was looking for perfectly.
Well, you can not use pointers.
void foreach(std::function<void(pNode)>);

C++ boost function issue

I did something to break the functionality in my program, but I can't figure out what. I define a typedef in a class headerfile:
typedef boost::function<void(instr_ptr, std::vector<ResultBase*>) > GenFunction;
And inside that class I have two instances:
GenFunction Gen;
GenFunction Kill
I set them as follows:
void DataFlowSolver::SetGenFunction(GenFunction &func)
{
Gen = func;
}
void DataFlowSolver::SetKillFunction(GenFunction &func)
{
Kill = func;
}
I have another function in a seperate header file:
void GenLiveVar(const instr_ptr instr, std::vector<ResultBase*> &list);
I create an instance of the DataFlowSolver class, and attempt to assign into it as follows:
blockSolver.SetGenFunction(GenLiveVar);
However, the compiler complains:
CFG.cc:617: error: no matching function for call to
'DataFlowSolver::SetGenFunction(void (&)(instr_ptr,
std::vector >&))'
DataFlowSolver.h:21: note: candidates are: void
DataFlowSolver::SetGenFunction(GenFunction&)
But it lets me do this:
GenFunction fun = GenLiveVar;
blockSolver.SetGenFunction(fun);
Anyone have an idea what might be wrong? I know this worked before, but I'm not sure how I managed to break it...
You are passing the boost::function into Set*Function by non-const reference. That prevents temporaries from being used as arguments, and the conversion from a normal function to a boost::function creates a temporary value. You will need to use a const reference for your parameter type for the code to work correctly.