LLVM — анализ живучести для удаления мертвого кода

Я пытаюсь реализовать анализ жизнеспособности, чтобы удалить мертвые инструкции. я знаю это isInstructionTriviallyDead() существует, однако, я хочу узнать, как удалить код, используя цепочки def-use (или use-def).

То, как я сейчас это делаю, я перебираю все инструкции в блоке (используя inst_iterator), и для каждой инструкции, циклически просматривая все ее применения. В конечном счете, если инструкция бесполезна, я считаю ее мертвой и поэтому могу удалить ее, используя eraseFromParent()

Это выглядит примерно так:

for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
bool deadInst = true;
Instruction *inst = &*I;for (User* pUser : inst->users()) {
// If we enter this loop, we have at least one use, so instruction isn't dead
deadInst = false;
}

// deadInst is true if we didn't enter the loop, so has no uses
if (deadInst) {
inst->eraseFromParent();
}
}

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

Мой общий подход к удалению инструкций через анализ жизнеспособности в порядке? Что я могу сделать, чтобы гарантировать, что инструкции, такие как возврат, не будут удалены?

Любые указатели очень ценятся 🙂

2

Решение

также проверьте, является ли инструкция терминатором (inst->isTerminator())

0

Другие решения

Ты упомянул llvm::isInstructionTriviallyDeadи это хорошее начало, чтобы получить представление о том, что можно удалить, а что нельзя.

Вы уже заметили, что не можете удалить инструкцию терминатора.

Кроме того, вы не хотите удалять инструкции без использования, но с побочными эффектами. Учти это:

define void @bar()() {
call void @foo()()
ret void
}

Вы не хотите удалять call инструкции, даже если она не имеет смысла, потому что она может, например, записать в стандартный вывод или изменить некоторую глобальную переменную. То же самое касается store«S. Проверьте Instruction::mayHaveSideEffects для полного списка.

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

Если вы не хотите использовать isInstructionTriviallyDead в учебных целях я рекомендую вам начать с другого пути: подумайте, когда инструкции наверняка не работают (например, alloca мертв, когда нет пользы, так же add инструкция …) а потом обобщать.

Кроме того, просто пройтись по всем инструкциям, и удаление мертвых недостаточно. Например:

%2 = add i32 3, %1
%3 = add i32 3, %2

Когда вы впервые сталкиваетесь %2это имеет применение в %3так что не мертвый. Но после устранения %3 как мертвый, %2 тоже становится мертвым Вы можете решить эту проблему, выполняя итерации до тех пор, пока не будет найдена новая мертвая инструкция (неэффективная, но простая), или с помощью некоторой рекурсивной процедуры.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector