<div dir="ltr"><div><div><div><div>Hello all,<br></div> I was playing with LLVM pass. I changed the lib/Transforms/Hello/Hello.cpp 's content to be my own pass. Then I make install the pass and use an example test1.c to see whether it works or not. When I run example using the following command: <br>
clang -emit-llvm test1.c -c -o test1.bc <br>opt -load ../build_llvm/Debug+Asserts/lib/LLVMHello.so -hello < test1.bc > /dev/null<br><br></div>It shows the following error:<br><br>Unknown instruction type encountered!<br>
UNREACHABLE executed at include/llvm/InstVisitor.h:120!<br>0 opt 0x00000000014190b6 llvm::sys::PrintStackTrace(_IO_FILE*) + 38<br>1 opt 0x0000000001419333<br>2 opt 0x0000000001418d8b<br>
3 libpthread.so.0 0x0000003aa600f500<br>4 libc.so.6 0x0000003aa5c328a5 gsignal + 53<br>5 libc.so.6 0x0000003aa5c34085 abort + 373<br>6 opt 0x000000000140089b<br>7 LLVMHello.so 0x00007f889beb5833<br>
8 LLVMHello.so 0x00007f889beb57bd<br>9 LLVMHello.so 0x00007f889beb575e<br>10 LLVMHello.so 0x00007f889beb56c5<br>11 LLVMHello.so 0x00007f889beb55f2<br>12 LLVMHello.so 0x00007f889beb5401<br>13 opt 0x00000000013a4e21 llvm::FPPassManager::runOnFunction(llvm::Function&) + 393<br>
14 opt 0x00000000013a5021 llvm::FPPassManager::runOnModule(llvm::Module&) + 89<br>15 opt 0x00000000013a5399 llvm::MPPassManager::runOnModule(llvm::Module&) + 573<br>16 opt 0x00000000013a59a8 llvm::PassManagerImpl::run(llvm::Module&) + 254<br>
17 opt 0x00000000013a5bbf llvm::PassManager::run(llvm::Module&) + 39<br>18 opt 0x000000000084b455 main + 5591<br>19 libc.so.6 0x0000003aa5c1ecdd __libc_start_main + 253<br>20 opt 0x000000000083d359<br>
Stack dump:<br>0. Program arguments: opt -load ../build_llvm/Debug+Asserts/lib/LLVMHello.so -hello <br>1. Running pass 'Function Pass Manager' on module '<stdin>'.<br>2. Running pass 'Hello Pass' on function '@main'<br>
<br></div>I will illustrate the pass code, the test1 example, and the IR generated below, so that anyone could help me or give me some suggestion. Thanks.<br><br></div>The Hello.cpp pass is as the following:<br><div><div>
<br><div><pre>#define DEBUG_TYPE "hello"
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/InstVisitor.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
namespace {
struct Hello : public llvm::FunctionPass, llvm::InstVisitor<Hello> {
private:
llvm::BasicBlock *FailBB;
public:
static char ID;
Hello() : llvm::FunctionPass(ID) {FailBB = 0;}
virtual bool runOnFunction(llvm::Function &F) {
visit(F);
return false;
}
llvm::BasicBlock *getTrapBB(llvm::Instruction &Inst) {
if (FailBB) return FailBB;
llvm::Function *Fn = Inst.getParent()->getParent();
llvm::LLVMContext& ctx = Fn->getContext();
llvm::IRBuilder<> builder(ctx);
FailBB = llvm::BasicBlock::Create(ctx, "FailBlock", Fn);
llvm::ReturnInst::Create(Fn->getContext(), FailBB);
return FailBB;
}
void visitLoadInst(llvm::LoadInst & LI) {
}
void visitStoreInst(llvm::StoreInst & SI) {
llvm::Value * Addr = SI.getOperand(1);
llvm::PointerType* PTy = llvm::cast<llvm::PointerType>(Addr->getType());
llvm::Type * ElTy = PTy -> getElementType();
if (!ElTy->isPointerTy()) {
llvm::BasicBlock *OldBB = SI.getParent();
llvm::errs() << "yes, got it \n";
llvm::ICmpInst *Cmp = new llvm::ICmpInst(&SI, llvm::CmpInst::ICMP_EQ, Addr, llvm::Constant::getNullValue(Addr->getType()), "");
llvm::Instruction *Iter = &SI;
OldBB->getParent()->dump();
llvm::BasicBlock *NewBB = OldBB->splitBasicBlock(Iter, "newBlock");
OldBB->getParent()->dump();
}
}
};
char Hello::ID = 0;
static llvm::RegisterPass<Hello> X("hello", "Hello Pass", false, false);
}
</pre> The test1.c example is as the following:<br><pre>#include <stdio.h>
void main() {
int x;
x = 5;
}<br><br></pre><pre>The IR for the example after adding the pass is as the following:<br>define void @main() #0 {
entry:
%x = alloca i32, align 4
%0 = icmp eq i32* %x, null
br label %newBlock
newBlock: ; preds = %entry
store i32 5, i32* %x, align 4
ret void
}<br></pre><br></div><div>any suggestion?<br></div></div></div></div>