2012-03-14 3 views
5

У меня есть ИК-файл followint LLVMСтирание первой инструкции в базовом блоке от LLVM IR?

%1 = load i32* %i, align 4 
    %2 = load i32* %j, align 4 
    %3 = icmp sgt i32 %1, %2 
    br i1 %3, label %4, label %6 

; <label>:4          ; preds = %0 
    %5 = load i32* %i, align 4 
    store i32 %5, i32* %k, align 4 
    br label %6 

; <label>:6          ; preds = %5, %0 
    ret i32 0 

В нем я первый загрузке vairable «я» в% 1 и переменная «J» в% 2, то я сравнив больше, чем условие, (я> к). На основании этого есть ветвь либо на метку 4, либо на ярлыке 6. Моя проблема в том, что есть две команды нагрузки для переменной «i» в первом базовом блоке и в другом базовом блоке. Здесь я хочу удалить вторую инструкцию загрузки. Для этого я делаю это так же, как при достижении второй инструкции нагрузки для переменной «i». Я заменяю все виды использования 2-й инструкции первой инструкцией, тогда я стираю текущую инструкцию, то есть вторую. Здесь я не могу установить указатель итератора инструкций. Я не хочу устанавливать следующую команду (хранить i32% 5, i32 *% k, выровнять 4). Есть ли другой способ? Если вы знаете, пожалуйста, дайте мне знать.

+0

Не уверен, что я понимаю ваш вопрос. Но я уверен, что последующие пропуски должны быть в состоянии легко удалить эту нагрузку для вас, поэтому я бы не стал беспокоиться. Если у вас есть веская причина для удаления нагрузки, пожалуйста, повторите свой вопрос, потому что я не могу понять, какова ваша проблема. – CAFxX

+0

Моя проблема в том, что после удаления второй инструкции загрузки я хочу установить итератор инструкций таким образом, чтобы на следующей итерации он должен был достигнуть (сохранить i32% 5, i32 *% k, align 4), потому что в цикле for я увеличиваю итератор команд , – damrudhard

+0

Почему бы просто не получить новый итератор, вызвав 'BB-> begin()' снова сразу после 'inst-> eraseFromParent()'? – CAFxX

ответ

10

Если вы правильно поняли, все, что вам нужно, это просто удалить инструкцию и продолжить итерацию кода. Если это так, посмотрите на этот пример из DeadInstElimintation прохода (который живет в lib/Transforms/Scalar/DCE.cpp):

virtual bool runOnBasicBlock(BasicBlock &BB) { 
    bool Changed = false; 
    for (BasicBlock::iterator DI = BB.begin(); DI != BB.end();) { 
    Instruction *Inst = DI++; 
    if (isInstructionTriviallyDead(Inst)) { 
     Inst->eraseFromParent(); 
     Changed = true; 
     ++DIEEliminated; 
    } 
    } 
    return Changed; 
} 

Интересно отметить, как увеличивается итератор. DI++ не выполняется внутри последнего предложения for, а скорее отдельно, с током DI, назначенным Inst. Это гарантирует, что даже если вы удалите Inst, DI уже указывает на следующую инструкцию, чтобы цикл продолжал работать над следующими инструкциями.

+0

У меня есть решение от CAFxX. Спасибо вам за вашу помощь. – damrudhard

+0

@damrudhard: установка нового итератора на 'BB-> begin()' будет работать, только если новая инструкция является первой в базовом блоке. В противном случае вы вернетесь к нескольким инструкциям. Если с вами все в порядке, тогда проблем нет. Я думаю, что решение, показанное в моем ответе, является более общим. –

+0

В другом случае я устанавливаю итератор команд в предыдущую инструкцию, так что в следующей итерации он укажет на инструкцию сразу после удаленной. – damrudhard

Смежные вопросы