2017-02-04 4 views
0

add 명령어를 포함하는 명령어 시퀀스로 add 명령어를 대체하기 때문에 아래 프로그램에서 ReplaceInstWithValue()을 사용하면 무한 루프가됩니다. 따라서, 프로그램은 `ReplaceInstWithValue()`를 사용하여 반복기를 무효화하는 것을 피하는 방법은 무엇입니까?

나는 문제가 즉 BasicBlock 지침, 반복이 수행되는리스트의리스트에 삽입되는 지침과 관련이있다 생각 ... xor, add, mul의 라인을 따라 뭔가를 인쇄합니다.

어떻게 삽입 된 지침을 무시하고 목록의 다음 요소로 진행할 수 있도록 문제를 해결합니까?

모든 삽입 지점을 데이터 구조에 넣고 반복이 완료된 후 대체를 수행하는 유일한 방법은 무엇입니까? w1ck3dg0ph3r가 지적 하듯이 bs를 증가되어야 할 때

#include "llvm/Pass.h" 
#include "llvm/IR/Function.h" 
#include "llvm/IR/BasicBlock.h" 
#include "llvm/IR/Instructions.h" 
#include "llvm/IR/IRBuilder.h" 
#include "llvm/Support/raw_ostream.h" 
#include "llvm/Transforms/Utils/BasicBlockUtils.h" 
#include <map> 
#include <string> 

using namespace llvm; 

namespace { 
struct CountOp : public FunctionPass {  
    static char ID; 

    CountOp() : FunctionPass(ID) {} 

    virtual bool runOnFunction(Function &F) { 

     for (Function::iterator bs = F.begin(), be = F.end(); bs != be; ++be) { 
      for (BasicBlock::iterator is = bs->begin(), ie = be->end(); is != ie; ++is) { 
       Instruction& inst = *is; 
       BinaryOperator* binop = dyn_cast<BinaryOperator>(&inst); 
       if (!binop) { 
        continue; 
       } 
       unsigned opcode = binop->getOpcode(); 
       errs() << binop->getOpcodeName() << "\n"; 

       if (opcode != Instruction::Add) { 

        continue; 
       } 

       IRBuilder<> builder(binop); 
       Value* v = builder.CreateAdd(builder.CreateXor(binop->getOperand(0), binop->getOperand(1)), 
              builder.CreateMul(ConstantInt::get(binop->getType(), 2), 
                   builder.CreateAnd(binop->getOperand(0), binop->getOperand(1)))); 

       ReplaceInstWithValue(bs->getInstList(), is, v); 
      } 
     } 

     errs() << "\n"; 
     return true; 
    } 
}; 
} 

char CountOp::ID = 0; 
static RegisterPass<CountOp> X("opCounter", "Counts opcodes per functions", false, false); 
+2

외부 루프가 증가하는 이유는 무엇입니까? – w1ck3dg0ph3r

+0

그것은 기본 블록입니다. – Shuzheng

답변

1

, 당신은 외부 루프에서 be를 증가한다. 이렇게하면 무한 루프 문제가 해결됩니다. llvm::IRBuilder은 iterator가 가리키는 명령어가 생성자에 전달되기 전에 명령어를 삽입하므로 다른 변경 작업은 필요하지 않습니다.

+0

실제로'++ bs '로 변경해도 문제가 해결되지 않습니다. 나는 여전히 무한 루프에 빠져있다. – Shuzheng

+0

'ReplaceInstWithValue'를 다른 것으로 대체해야한다고 제안합니까? – Shuzheng

+0

이상 하네. 패스 재 컴파일을 기억하십니까? 예제 LLVM IR 입력을 제공 할 수 있습니까? 나는 그것을 직접 테스트하고 잘 작동한다 : http://pastebin.com/dR8dbhCu – SPAT