I am trying to write a pass, that finds some instructions and replaces them with my intrinsics,
but I am having problem understanding, how this should be done.
Let's say I have this instruction:
%tmp14 = load i32* getelementptr ([32 x i32]* @gpregs, i32 0, i64 28)
and i need to read the load's operands and replace it by let's say:
%tmp14 = call i32 @llvm.regread_i32.i32(i32 0, i32 1)
Here is what I have:
//for each instruction of a function
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
{
Instruction* i = &(*I);
//if this is a load
if (isa<LoadInst>(i))
{
//now i need to create an instruction that represents a call to a intrinsic
Function* FIntr = Intrinsic::getDeclaration(&M, Intrinsic::regread_i32);
// here it fails: void llvm::CallInst::init(llvm::Value*):
//Assertion `FTy->getNumParams() == 0 && "Calling a function with bad signature"' failed.
Instruction* Instr = CallInst::Create(FIntr);
//do some stuff with the operands
//and replace it
ReplaceInstWithInst(i, Instr);
}
}
Intrinsic regread_i32 is defined in Intrinsics.td as follows:
//represents register value read, as arguments takes 1) register class number (determined from the acessed variable, here 'regs') and 2) register operand index (not important now)
def int_regread_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
The problem is, that I have not found yet, how to correctly create an intrinsic instruction and
how do I access and set operands. Is there some documentation, how is the LLVM IR API designed?
Or, has someone already tried to solve similar problem? (I am already trying to learn from the source code how it works,
but I thought that asking you would be faster:)
Thank you
Adam
btw.: Is there a way how to search archived messages from this mailing list? Google with site:lists.cs.uiuc.edu
does not work very much.
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
> btw.: Is there a way how to search archived messages from this mailing list?
> Google with site:lists.cs.uiuc.edu
> does not work very much.
Try http://www.nabble.com/LLVM---Dev-f692.html
--Sam
You have to include the operands in the call to CallInst::Create.
-Eli
> On Thu, Jun 25, 2009 at 12:32 AM, ihusar<ihu...@fit.vutbr.cz> wrote:
>> //now i need to create an instruction that represents a call to a intrinsic
>> Function* FIntr = Intrinsic::getDeclaration(&M, Intrinsic::regread_i32);
>>
>> // here it fails: void llvm::CallInst::init(llvm::Value*):
>> //Assertion `FTy->getNumParams() == 0 && "Calling a function with bad signature"' failed.
>> Instruction* Instr = CallInst::Create(FIntr);
>
> You have to include the operands in the call to CallInst::Create.
>
> -Eli
Hi, I created arguments as you told and now everything works fine. If someone would be interested, I am putting the code here.
Adam
void CGInstrOpRewriter::replaceByIntrinsic(Module& M, Instruction* instrToReplace, const Intrinsic::ID intrId, const int arg1, const int arg2)
{
//create function and its arguments
Function* FIntr = Intrinsic::getDeclaration(&M, intrId);
SmallVector<Value*, 2> Args(2);
Args[0] = ConstantInt::get(Type::Int32Ty, arg1);
Args[1] = ConstantInt::get(Type::Int32Ty, arg2);
//now create and replace original instruction
Instruction* IntrI = CallInst::Create(FIntr, Args.begin(), Args.end());
ReplaceInstWithInst(instrToReplace, IntrI);
}
bool CGInstrOpRewriter::runOnModule(Module &M)
{
if (!bLoaded)
{
llvm::cerr << "CG: Error: Ignoring module\n"; //should not happen
return false;
}
//for each function in module
for(Module::iterator FuncIt = M.getFunctionList().begin(); FuncIt != M.getFunctionList().end(); FuncIt++)
{
Function* F = FuncIt;
llvm::cerr << "Original ---- \n" << *F << "\n";
//and for each instruction of a function
for (inst_iterator It = inst_begin(F), E = inst_end(F); It != E; ++It)
{
//previous iterator
inst_iterator PrevIt;
bool bFirst = false;
if (It == inst_begin(F))
{
bFirst = true;
}
else
{
PrevIt = It;
--PrevIt;
}
Instruction* CurrI = &(*It);
llvm::cerr << "Processing " << *CurrI << "\n";
if (isa<LoadInst>(CurrI))
{
//replace - intrinsics ID (from Intrinsics.def) and some int arguments
replaceByIntrinsic(M, CurrI, Intrinsic::regread_i32, 1, 2);
//renew iterator because we removed previous instruction to which it was pointing
if (!bFirst)
{
It = ++PrevIt;
}
else
{
It = ++inst_begin(F);
}
}
}
llvm::cerr << "Modified ---- \n" << *F << "\n";
}
return true;