удалить цикл командой eraseFromParent в llvm - PullRequest
5 голосов
/ 06 октября 2011

* Я бы удалил цикл.Я использовал следующий код:

cout << "begin to delete loop" << endl;
for (Loop::block_iterator bi = L->block_begin(), bi2; bi != L->block_end(); bi = bi2) {
    bi2 = bi;
    bi2++;
    BasicBlock * BB = *bi;
    for (BasicBlock::iterator ii = BB->begin(), ii2; ii != BB->end(); ii= ii2) {
        ii2 = ii;
        ii2++;
        Instruction *inst = ii;
        inst->eraseFromParent();
    }
    BB->eraseFromParent();
}

Но я получаю следующую ошибку:

Использование по-прежнему застревает после уничтожения Def:% t1 = icmp sle i32% t0, 9 opt: /home / llvm / src / lib / VMCore / Value.cpp: 75: виртуальный llvm :: Value :: ~ Value (): утверждение `use_empty () &&" Использование сохраняется, когда значение уничтожается! "'не удалось.0 opt 0x0848e569 Дамп стека:

Какие у вас есть предложения по решению этой проблемы? *

Ответы [ 4 ]

6 голосов
/ 04 декабря 2012

Решение вашей проблемы заключается в следующем:

убедитесь, что для каждой инструкции в цикле сброшены все ссылки, а затем просто удалите все базовые блоки цикла.

вот мой пример кода

for (Loop::block_iterator block = CPLoop->block_begin(), end = CPLoop->block_end(); block != end; block++) {
        BasicBlock * bb = *block;
        for (BasicBlock::iterator II = bb->begin(); II != bb->end(); ++II) {
            Instruction * insII = &(*II);
            insII->dropAllReferences();
        }
    }
    for (Loop::block_iterator block = CPLoop->block_begin(), end = CPLoop->block_end(); block != end; block++) {
        BasicBlock * bb = *block;
        bb->removeFromParent();
    }

Надеюсь, это поможет

3 голосов
/ 05 декабря 2011

То, что я пишу, является лишь предположением, потому что я только начинаю с LLVM, но я надеюсь, что это будет полезно.

В SSA Форма каждой инструкции:

  • использует значения, предоставленные ранее выполненными инструкциями
  • предоставляет значение (с результатом выполнения этой инструкции), которое используется другими.

Это так называемые цепочки use-def и def-use.

Если вы попытаетесь удалить инструкцию, результат которой (a.k.a. «предоставленное значение») используется другими инструкциями, чем вы разрываете цепочку инструкций.

Возможно, вас заинтересует итерация пользователей, которых вы удаляете, используя:

Руководство программиста LLVM: перебор цепочек def-use и use-def . Благодаря этому вы можете перебирать пользователей ( u ) значения, предоставленные инструкцией, вы хотите удалить ( inst ) и изменить их ссылку на другую (например, ) inst: add uv -> add X v ). Если вы уверены, что никто не использует инструкцию, которую вы хотите удалить, удалите ее. (В зависимости от того, были ли пройдены этапы анализа, вам может потребоваться, чтобы llvm pass manager знал, что анализ CFG необходимо обновить - если вы не обновите их самостоятельно).

2 голосов
/ 16 апреля 2014

Вы делаете недействительным итератор, вызывая

inst->eraseFromParent();

Сохраняйте все Instruction* в std::vector или аналогичном и пакетно удаляйте их в конце вашего прохода.Это должно решить вашу проблему.

0 голосов
/ 29 июня 2016

Существует альтернативное решение для «удаления» цикла: просто навсегда отключите его. То есть изменить ИК-код от чч как это:

  ...
  br label %loop
loop:
  <loop body>
  br i1 %exitcond, label %exit, label %loop
exit:
  ...

чч как это:

...
  br i1 0, label %loop, label %exit
loop:
  <loop body>
  br i1 %exitcond, label %exit, label %loop
exit:
  ...

Вы, вероятно, в любом случае будете запускать оптимизации (например, устранение мертвого кода) на сгенерированном IR, так зачем бороться со всеми ссылками на цикл (например, в LoopInfo s или ValueMap s)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...