[LLVMdev] Adding function attributes

520 views
Skip to first unread message

Arnaldo

unread,
Nov 4, 2012, 11:48:16 PM11/4/12
to llv...@cs.uiuc.edu
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
====
virtual bool runOnModule(Module& m)
{
    Module* module = &m;

    for (Module::iterator functionIter = module->begin(); functionIter != module->end(); functionIter++)
        functionIter->addFnAttr(llvm::Attributes::AlwaysInline);
   
    return true;
}


Command line
===========
clang -O0 -S -emit-llvm -o test.S test.c && opt -S -mem2reg -load <path to lib> -mypass < test.S > test_opt.S

Duncan Sands

unread,
Nov 5, 2012, 3:03:43 AM11/5/12
to llv...@cs.uiuc.edu
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.

>
> Any help is much appreciated
>
>
> Code
> ====
> virtual bool runOnModule(Module& m)
> {
> Module* module = &m;
>
> for (Module::iterator functionIter = module->begin(); functionIter !=
> module->end(); functionIter++)
> functionIter->addFnAttr(llvm::Attributes::AlwaysInline);
>
> return true;
> }
>
>
> Command line
> ===========
> clang -O0 -S -emit-llvm -o test.S test.c && opt -S -mem2reg -load <path to lib>
> -mypass < test.S > test_opt.S
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>

_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

Arnaldo

unread,
Nov 5, 2012, 4:02:01 AM11/5/12
to Duncan Sands, llv...@cs.uiuc.edu
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.

Duncan Sands

unread,
Nov 5, 2012, 4:04:24 AM11/5/12
to Arnaldo, llv...@cs.uiuc.edu
Hi Arnaldo,

On 05/11/12 10:02, Arnaldo wrote:
> 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.

>
>
> On Mon, Nov 5, 2012 at 5:03 PM, Duncan Sands <bald...@free.fr
> <mailto:bald...@free.fr>> wrote:
>
> 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.
>
>
> Any help is much appreciated
>
>
> Code
> ====
> virtual bool runOnModule(Module& m)
> {
> Module* module = &m;
>
> for (Module::iterator functionIter = module->begin(); functionIter !=
> module->end(); functionIter++)
> functionIter->addFnAttr(llvm::__Attributes::AlwaysInline);
>
> return true;
> }
>
>
> Command line
> ===========
> clang -O0 -S -emit-llvm -o test.S test.c && opt -S -mem2reg -load <path
> to lib>
> -mypass < test.S > test_opt.S
>
>
>
> _________________________________________________
> LLVM Developers mailing list
> LLV...@cs.uiuc.edu <mailto:LLV...@cs.uiuc.edu> http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/__mailman/listinfo/llvmdev
> <http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev>
>
>
> _________________________________________________
> LLVM Developers mailing list
> LLV...@cs.uiuc.edu <mailto:LLV...@cs.uiuc.edu> http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/__mailman/listinfo/llvmdev

Arnaldo

unread,
Nov 5, 2012, 7:44:58 PM11/5/12
to Duncan Sands, llv...@cs.uiuc.edu
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 <path to extract lib> -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<LoopInfo>();
                analysisUsage.addPreserved<LoopInfo>();
                analysisUsage.addRequired<ScalarEvolution>();
                analysisUsage.addPreserved<ScalarEvolution>();
                analysisUsage.addRequired<DependenceAnalysis>();
                analysisUsage.addPreserved<DependenceAnalysis>();
            }

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

    char ExtractFeatures::ID = 0;

    static RegisterPass<ExtractFeatures> X("extract", "Extract source features", true, true);
}


Arnaldo

unread,
Nov 5, 2012, 9:05:15 PM11/5/12
to Duncan Sands, llv...@cs.uiuc.edu
The code above is working, somehow I screwed up on my compilation script.
Reply all
Reply to author
Forward
0 new messages