I need to get hold of ScalarEvolution object inside LLVM loop pass. I know that we can get it from
LoopStandardAnalysisResults object while using new pass manager. Is it possible to get the scalarEvolution analysis using old / legacy loop pass ?
After some code search I found we can do like below :
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
auto *SE = getAnalysisIfAvailable<ScalarEvolutionWrapperPass>();
}
Related
I have a Function pass, called firstPass, which does some analysis and populates:
A a;
where
typedef std::map< std::string, B* > A;
class firstPass : public FunctionPass {
A a;
}
typedef std::vector< C* > D;
class B {
D d;
}
class C {
// some class packing information about basic blocks;
}
Hence I have a map of vectors traversed by std::string.
I wrote associated destructors for these classes. This pass works successfully on its own.
I have another Function pass, called secondPass, needing this structure of type A to make some transformations. I used
bool secondPass::doInitialization(Module &M) {
errs() << "now running secondPass\n";
a = getAnalysis<firstPass>().getA();
return false;
}
void secondPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<firstPass>();
AU.setPreservesAll();
}
The whole code compiles fine, but I get a segmentation fault when printing this structure at the end of my first pass only if I call my second pass (since B* is null).
To be clear:
opt -load ./libCustomLLVMPasses.so -passA < someCode.bc
prints in doFinalization() and exits successfully
opt -load ./libCustomLLVMPasses.so -passA -passB < someCode.bc
gives a segmentation fault.
How should I wrap this data structure and pass it to the second pass without issues? I tried std::unique_ptr instead of raw ones but I couldn't make it work. I'm not sure if this is the correct approach anyway, so any help will be appreciated.
EDIT:
I solved the problem of seg. fault. It was basically me calling getAnalysis in doInitialization(). I wrote a ModulePass to combine my firstPass and secondPass whose runOnModule is shown below.
bool MPass::runOnModule(Module &M) {
for(Function& F : M) {
errs() << "F: " << F.getName() << "\n";
if(!F.getName().equals("main") && !F.isDeclaration())
getAnalysis<firstPass>(F);
}
StringRef main = StringRef("main");
A& a = getAnalysis<firstPass>(*(M.getFunction(main))).getA();
return false;
}
This also gave me to control the order of the functions processed.
Now I can get the output of a pass but cannot use it as an input to another pass. I think this shows that the passes in llvm are self-contained.
I'm not going to comment on the quality of the data structures based on their C++ merit (it's hard to comment on that just by this minimal example).
Moreover, I wouldn't use the doInitialization method, if the actual initialization is that simple, but this is a side comment too. (The doc does not mention anything explicitly about it, but if it is ran once per Module while the runOn method is ran on every Function of that module, it might be an issue).
I suspect that the main issue seems to stem from the fact A a in your firstPass is bound to the lifetime of the pass object, which is over once the pass is done. The simplest change would be to allocate that object on the heap (e.g. new) and return a pointer to it when calling getAnalysis<firstPass>().getA();.
Please note that using this approach might require manual cleanup if you decide to use a raw pointer.
I was wondering how could I update the data on the DOM for a certain attribute? I've searched but I couldn't find anything. Basically, I have an attribute called Hour(for example it's "11:03") and I want the text from that specific attribute to be changed to something like "11:04" or any other different text.
if( strcmp(Code1,Code2) == 0 )
{
strcpy(New,NewHour);
Element->FindAttribute("Hour")->SetAttribute(New); // here I want it to be changed in the DOM but I dont know how to do it
}
Later edit: This is what I've tried, but it's telling me FindAttribute() is private..
It is true that you can use SetAttribute which accepts the attribute name and value as parameters.
However, TinyXml2 does have a methodology for using FindAttribute because I have this code in my application:
// We need to get the assistant
const XMLAttribute *pAttrAssistant = const_cast<const XMLElement*>(pStudent)->FindAttribute("Assistant");
if (pAttrAssistant != nullptr)
{
LPCTSTR szAssistant = CA2CT(pAttrAssistant->Value(), CP_UTF8);
SetStudentInfo(eSchool, eAssign, strStudent, szAssistant, iStudyPoint);
}
else
{
// TODO: Throw exception if Assistant attribute missing
}
As you can see, I use the FindAttribute method and I have no compilation errors. If you look closely you will see that I am using const and that is the key.
The class exposes two methods:
One of them is set to private as you have already found out. But the const overload is set as public:
I’m writing a CallGraphSCCPass which needs dominator tree information on each function. My getAnalysisUsage is fairly straightforward:
virtual void getAnalysisUsage(AnalysisUsage& au) const override
{
au.setPreservesAll();
au.addRequired<DominatorTreeWrapperPass>();
}
The pass is registered like this:
char MyPass::ID = 0;
static RegisterPass<MyPass> tmp("My Pass", "Do fancy analysis", true, true);
INITIALIZE_PASS_BEGIN(MyPass, "My Pass", "Do fancy analysis", true, true)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(MyPass, "My Pass", "Do fancy analysis", true, true)
When I try to add my pass to a legacy::PassManager, it dies with this error message:
Unable to schedule 'Dominator Tree Construction' required by ‘My Pass'
Unable to schedule pass
UNREACHABLE executed at LegacyPassManager.cpp:1264!
I statically link LLVM to my program, and define the pass in my program, too.
Am I doing something wrong? Does it make sense to require the DominatorTreeWrapperPass from a CallGraphSCCPass?
I also sent the question on the LLVM ML, but the server appears to be down at the moment.
If it makes any difference, I'm using LLVM 3.7 trunk, up-to-date as of a few weeks ago.
CallGraphSCCPass appears to be a special case that doesn't support every analysis very well. The simplest thing to do is to convert the pass to a ModulePass, and use <llvm/ADT/SCCIterator.h> to construct call graph SCCs from runOnModule, like how CGPassManager does it.
virtual void getAnalysisUsage(AnalysisUsage& au) const override
{
au.addRequired<CallGraphWrapperPass>();
// rest of your analysis usage here...
}
virtual bool runOnModule(Module& m) override
{
CallGraph& cg = getAnalysis<CallGraphWrapperPass>().getCallGraph();
scc_iterator<CallGraph*> cgSccIter = scc_begin(&cg);
CallGraphSCC curSCC(&cgSccIter);
while (!cgSccIter.isAtEnd())
{
const vector<CallGraphNode*>& nodeVec = *cgSccIter;
curSCC.initialize(nodeVec.data(), nodeVec.data() + nodeVec.size());
runOnSCC(curSCC);
++cgSccIter;
}
return false;
}
bool runOnSCC(CallGraphSCC& scc)
{
// your stuff here
}
Module passes take no issue at requiring DominatorTreeWrapperPass, or other analyses like MemoryDependenceAnalysis. However, this naive implementation might not support modifications to the call graph like CGPassManager does.
CallGraphSCCPass is a ModulePass and hence is being handled and invoked by ModulePassManager, ModulePassManager invokes FunctionPassManager (which manages FunctionPasses) and gives the handle to it after invoking Module passes(in the other word ModulePasses queue before FunctionPasses in the PassManager's pipeline), so you can not ask PassManager for a functionPass while you are inside a ModulePass but you can ask for a ModulePass inside FunctionPass since they already have run. by the same reason you can not ask for a LoopPass inside a FunctionPass
I still shocked after detecting a mysterious issue on our project.
We realized that calling HasMember("string") was performing an extra seek. So, for performance reasons, we change it.
The main idea is:
Instead of calling HasMember and afterwards precaching the reference like:
rapidjson::Document d;
d.Parse<0>(json);
if(d.HasMember("foo"))
{
const rapidjson::Value& fooValue = d["foo"];
// do something with fooValue
}
Changed to:
rapidjson::Document d;
d.Parse<0>(json);
const rapidjson::Value& fooValue = d["foo"];
if( !fooValue.IsNull() )
{
// do something with fooValue
}
This was pretty good, we save to perform two seeks instead of only one. However, here it comes the issue.
If you start looking how rapidjson implements nullvalue (returned by default when seek fails) you will see the following code:
//! Get the value associated with the object's name.
GenericValue & operator[](const Ch* name) {
// Check
if (Member * member = FindMember(name)) {
return member->value;
} else {
// Nothing
static GenericValue NullValue;
return NullValue;
}
}
// Finder
const GenericValue & operator[] (const Ch* name) const {
// Return
return const_cast<GenericValue &> (* this)[name];
}
So, if didn't find the member we return a local static variable. This may sound good enough at first glance but since this is returning by reference can lead easily to hidden bugs.
Imagine that someone change the reference of the static NullValue. This will cause that all further calls to IsNull (after looking for it) will fail because the NullValue changed to another type or even to random memory.
So, what do you thing? Do you think this is a good null pattern example?
I am confused, I like the idea of returning a default null value but since is not returned as const this is dangerous. And, even, if we do return it in all cases as const, devs can still use const_cast (but I wouldn't expect that, if they do, will be under them responsibility).
I want to hear other cases and examples like this one. And if someone can give a real solution under rapidjson code would be basically awesome and amazing.
The pitfall of this design has been raised up by the community long time ago. Since operator[] also needs a non-const version, it is not possible to maintain the integrity of the static variable.
So this API has been changed in newer versions of RapidJSON. The operator[] simply assert for non-exist key. If it is unsure that a key is exist, it is preferably using
MemberIterator FindMember(const Ch* name);
ConstMemberIterator FindMember(const Ch* name) const;
And comparing the value with MemberEnd() to check whether the key exists. This is also documented here.
Besides, please note that RapidJSON has been moved to GitHub. Many issues has been resolved. Please use the newest version if possible. Thank you.
P.S. I am the author of RapidJSON.
I extended the LLVM Kaleidoscope example to support Strings. I added a StringExprAST, which has the virtual Codegen method impl as follows:
Value *StringExprAST::Codegen() {
StringRef r(Val);
return ConstantDataArray::getString(getGlobalContext(), r, false);
}
I am trying to concatenate Strings and have a ConcatExprAST with its Codegen method. Upon trying to access the data in the ConstantDataArray, I need to cast the Value* back to a ConstantDataArray* in order to use the getAsString() method.
How can I do this?
Thanks for any help.
The proper way to cast any subtype of Value to another is via cast<>(), e.g.:
Value* v = ...
ConstantDataArray* result = cast<ConstantDataArray>(v);
However, keep in mind that in your example you don't return an object of type ConstantDataArray, but you return something of the return type of ConstantDataArray::getString(), which is not necessarily an instance of ConstantDataArray itself, all you know is that it's a Constant (for instance, it might be a ConstantAggregateZero, which is not a ConstantDataArray).
In any case, if you're not sure that v is indeed of a specific type, check it first with isa<>() (or use the dyn_cast<>() idiom), before performing the cast<>().