2017-06-12 6 views
0

Ich versuche, eine Reihe von Anweisungen zu löschen (angegeben zwischen [startIns, endIns)). Die EndIns befinden sich möglicherweise nicht im selben Basisblock wie der Start.Löschen einer Reihe von Anweisungen in llvm

Ich erhalte den folgenden Fehler beim Versuch, die letzte Anweisung in löschen - Referenz llvm :: ilist_iterator, falsch, false> :: operator *() const [OptionsT = llvm :: ilist_detail :: node_options, IsReverse = false, IsConst = false]: Assertion `! NodePtr-> isKnownSentinel() 'ist fehlgeschlagen.

Es folgt mein C++ Code -.

// löschen Sie alle Anweisungen zwischen [Beginn, Ende)

// startInst ist "%res = alloca i8 " in IR unter“

// endInst ist "%resclone0 = alloca i10" in IR unten.

void deleteAllInstructionsInRange(Instruction* startInst,Instruction* endInst) 
    { 
     BasicBlock::iterator it(startInst); 
     BasicBlock::iterator it_end(endInst); 

     Instruction* currentInst ; 

     while(it != it_end) 
     { 
      currentInst = &*it; 

      ++it; 


      if (!currentInst->use_empty()) 
      { 
       currentInst->replaceAllUsesWith(UndefValue::get(currentInst->getType())); 
      } 

      currentInst->eraseFromParent(); 

     } 



    } 

Es folgt die entsprechende IR

define i32 @test2() { 
entry: 
    %calltmp = call i32 @UInt() 
    %datasize = alloca i32 
    switch i32 %calltmp, label %sw.bb.0 [ 
    i32 1, label %sw.bb.1 
    i32 2, label %sw.bb.2 
    i32 3, label %sw.bb.3 
    ] 
; %res = alloca i8      ===> deleted 
    ;store i8 0, i8* %res     ===> deleted 
    ;%datasize1 = load i32, i32* %datasize ===> deleted 

    ret i32 %datasize1      ===> UNABLE to delete 

sw.bb.0:           ; preds = %entry 
    %resclone0 = alloca i10 
    store i10 0, i10* %resclone0 
    %datasize1clone0 = load i32, i32* %datasize 

Jede Hilfe wird geschätzt.

Danke.

Antwort

0

Zuerst sehen Sie sich this Antwort zu verstehen, was istKnownSentinel() bedeutet.

Meine Vermutung ist, dass, da Sie den Basisblock während der Iteration ändern, die nicht sicher ist und Sie den Fehler erhalten.

+0

Ich weiß schon, was Sentinel für llvm bedeutet, und Sie sind richtig über die Tatsache, dass ich das bin Modifizieren BB während der Iteration. Daher habe ich die Anweisungen einfach in einem Vektor gespeichert und sie später gelöscht. – mal

0

Meine Vermutung ist, dass ret ist ein Terminator und das Löschen würde das IR ungültig machen. Zitiert this question:

Jeder Basisblock muss mit einem Terminator beenden.

Ich schlage vor, Terminator Anweisungen mit uncondicional Sprung zum nächsten Block zu ersetzen (nicht getestet):

if (currentInst->isTerminator()) { 
    // works only if block has only one successor 
    currentInst->replaceAllUsesWith(
     builder->CreateBr(
      builder->GetInsertBlock()->getSingleSuccessor())); 
}