Adding function attributes

Hello everyone,

I am coding a ModulePass in which I want to add an AlwaysInline attribute to every function so that they can be later inlined by the -always-inline pass. However, the changes to the function seem to be lost after exiting my pass because the AlwaysInline attribute is not in the output LLVM IR.

Maybe the function iterator passed by the module object actually points to copies of the functions?

Any help is much appreciated

Code

Hi Arnaldo,

I am coding a ModulePass in which I want to add an AlwaysInline attribute to
every function so that they can be later inlined by the -always-inline pass.

why not just do the inlining yourself. The always inliner code is at
lib/Transforms/IPO/InlineAlways.cpp, and it's pretty short.

However, the changes to the function seem to be lost after exiting my pass
because the AlwaysInline attribute is not in the output LLVM IR.

Maybe the function iterator passed by the module object actually points to
copies of the functions?

As far as I can see your code should work. Most likely it isn't being run
at all - did you check that your runOnModule method is actually being called?

Ciao, Duncan.

Hi Duncan, thanks for the quick answer.

Yes I’m sure the runOnModule is being called, and when I dump the functions before exiting the method I can see the AlwaysInline attribute.

I’ll check InlineAlways.cpp and will reimplement as last resource but I still wonder why this is not working.

Hi Arnaldo,

Hi Duncan, thanks for the quick answer.

Yes I'm sure the runOnModule is being called, and when I dump the functions
before exiting the method I can see the AlwaysInline attribute.

I'll check InlineAlways.cpp and will reimplement as last resource but I still
wonder why this is not working.

if you want more help with this please provide the complete code for your pass.

Ciao, Duncan.

Below is a stripped down version of the pass.
The compile line is: clang -O0 -S -emit-llvm -o test.S test.c && opt -S -mem2reg -load -extract < test.S > test_opt.S

#include “llvm/Analysis/DependenceAnalysis.h”
#include “llvm/Analysis/LoopInfo.h”
#include “llvm/Analysis/LoopPass.h”
#include “llvm/Analysis/ScalarEvolution.h”
#include “llvm/Function.h”
#include “llvm/Module.h”
#include “llvm/Pass.h”
#include “llvm/Support/raw_ostream.h”

using namespace llvm;
using namespace std;

namespace
{
class ExtractFeatures : public ModulePass
{
public:
static char ID;

ExtractFeatures() : ModulePass(ID)
{
module = NULL;
loopInfo = NULL;
scalarEvolution = NULL;
}

virtual bool runOnModule(Module& m)
{
module = &m;
bool modified = false;

for (Module::iterator functionIter = module->begin(); functionIter != module->end(); functionIter++)
{
if (functionIter->isDeclaration())
continue;

Attributes attributes = functionIter->getFnAttributes();
if (!attributes.hasAttribute(Attributes::AlwaysInline))
{
functionIter->addFnAttr(llvm::Attributes::AlwaysInline);

errs() << “AlwaysInline NOT detected\n”;

modified = true;
}
else
{
errs() << “AlwaysInline detected\n”;
}
}

return modified;
}

virtual void getAnalysisUsage(AnalysisUsage &analysisUsage) const
{
analysisUsage.addRequired();
analysisUsage.addPreserved();
analysisUsage.addRequired();
analysisUsage.addPreserved();
analysisUsage.addRequired();
analysisUsage.addPreserved();
}

private:
DependenceAnalysis* dependenceAnalysis;
LoopInfo* loopInfo;
Module* module;
ScalarEvolution* scalarEvolution;
};

char ExtractFeatures::ID = 0;

static RegisterPass X(“extract”, “Extract source features”, true, true);
}

The code above is working, somehow I screwed up on my compilation script.