I’m trying to use LLVM Create and replaceAllUsesWith to modify the (A+B+C) calculation to (A*B)-C
The ReplaceInst.cpp code I wrote is this,
// Traverse Instructions in TheModule
void TraverseModule(void)
{
for( llvm::Module::iterator ModIter = TheModule->begin(); ModIter != TheModule->end(); ++ModIter )
{
llvm::Function* Func = llvm::cast<llvm::Function>(ModIter);
for( llvm::Function::iterator FuncIter = Func->begin(); FuncIter != Func->end(); ++FuncIter )
{
llvm::BasicBlock* BB = llvm::cast<llvm::BasicBlock>(FuncIter);
std::vector< llvm::Instruction* > AddInsts;
for( llvm::BasicBlock::iterator BBIter = BB->begin(); BBIter != BB->end(); ++BBIter )
{
llvm::Instruction* AddInst = llvm::cast<llvm::Instruction>(BBIter);
// if( Inst->isBinaryOp() ) {}
if( AddInst->getOpcode() == llvm::Instruction::Add )
{
if (AddInst->getNumOperands() != 2) {
std::cerr << "Error: Add instruction does not have exactly 2 operands." << std::endl;
continue;
}
llvm::LLVMContext& context = AddInst->getContext();
llvm::Instruction* MulInst = llvm::BinaryOperator::Create(
llvm::Instruction::Mul, /* Opcode */
AddInst->getOperand(0), /* S1 */
AddInst->getOperand(1), /* S2 */
"multmp", /* Name */
AddInst /* BeforeInst */ );
// replace sign extend(sext)
llvm::Instruction* SextInst = llvm::CastInst::Create(
llvm::Instruction::SExt, /* Opcode */
MulInst, /* S1 */
llvm::Type::getInt64Ty(context), /* S2 */
"sextmp", /* Name */
AddInst /* BeforeInst */
);
llvm::Value* CPointer = AddInst->getOperand(1);
// replace load
llvm::Instruction* LoadInst = new llvm::LoadInst(
llvm::Type::getInt64Ty(context),
CPointer,
"loadtmp",
AddInst
);
// replace sub
llvm::Instruction* SubInst = llvm::BinaryOperator::Create(
llvm::Instruction::Sub,
SextInst,
LoadInst,
"subtmp",
AddInst
);
AddInst->replaceAllUsesWith( SubInst );
AddInsts.push_back( AddInst );
}
}
for( int i=0, Size=AddInsts.size(); i<Size; ++i ) AddInsts[i]->eraseFromParent();
}
}
}
This is the Test.c code
#include <stdlib.h>
#include <stdio.h>
int Add(int*arr,int*brr,int*crr,size_t n)
{
crr[n]= arr[n]+brr[n]+n;
return crr[n];
}
int main()
{
int N=0;
printf("Input N (0~5)n");
scanf("%d",&N);
int crr[5]={0,0,0,0,0};
int arr[5]={1,2,3,4,5};
int brr[5]={2,3,4,5,6};
int result = Add(arr,brr,crr,N);
printf("...(%d MUL %d) SUB %d = %dn" ,arr[N],brr[N],N,result);
}
The vimdiff of the original ll code and replaced ll code seems correct, and it is what I intended.
When when I make ll code from Test.c code and compile it, below error occurs.
Can I write the cpp code without replacing the signextend part? Or is there any more optimized to this problem?
I tried getting rid of replacing the signextend part, but it didn’t work.