2013-11-07 2 views
1

Я разделяя все основные блоки с минимальным количеством команд (обычно 3-5):LLVM: Инструкция не доминирует все использует

llvm::SplitBlock(BasicBlock, &*BasicBlockiter, Pass); 

и пытаюсь получить объектный файл из ИК

llc -filetype=obj 2.ll 

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

Instruction does not dominate all uses! 
    %1 = alloca i32 
    %mul = load i32* %1 
Instruction does not dominate all uses! 
    %1 = alloca i32 
    %99 = load i32* %1 

и

While deleting: i32 % 
Use still stuck around after Def is destroyed: %var = alloca i32 
Assertion failed: use_empty() && "Uses remain when a value is destroyed!" 

и

error: expected instruction opcode 
invoke.cont2:          ; preds = %main_block, %invoke 
.cont 

ИК:

invoke.cont2:          ; preds = %main_block, %invoke.cont 
    %call4 = invoke i32 @_ZStorSt13_Ios_OpenmodeS_(i32 8, i32 16) 
      to label %invoke.cont3 unwind label %lpad1 
    store i32 %call4, i32* %var4 

Я думаю, что после расщепления, инструкции расположены в различных базовых блоках. Если я разделяю блок на 10-15 инструкций, все в порядке. Как я могу предсказать/проверить и избежать этих ошибок?

+0

Если ваш пропуск просто расщепляет basicblocks, и принимает в качестве входных правильный IR-файл, то нет причин для ошибок доминирования в полученном IR. Есть некоторая причина, которая может вызвать такую ​​ошибку: * вы переехали или создали новые инструкции * вы добавили переходы между базовыми блоками, которые не существовали до –

+1

Это поможет, если вы предоставили более подробную информацию. Минимальный LLVM IR-фрагмент кода * перед * расщеплением, а затем * после * расщепления. В общем, что @JulienH. сказал смысл. –

+0

Прошу прощения, у меня есть другие проходы, и один из них добавляет/изменяет инструкции через llvm :: InlineAsm и llvm :: ReplaceInstWithInst – Denis

ответ

1

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

В вашей второй версии (не упоминается здесь, используйте stackoverflow вместо частных сообщений электронной почты ...) используют% вызова (в магазине inst) перед его определением (% call = ...), поэтому четко ваше определение не предшествует каждому использованию ... Но, как я уже сказал, хранилище не должно быть после вызова, потому что invoke является terminatorinst.

Решение поместить ваш магазин в следующем базовом блоке (вы можете создать новый):

%invoke.cont 
    %call = invoke i8* @_ZNKSs5c_strEv(%"class.std::basic_string"* @loadedFile) 
      to label %invoke.cont2_before unwind label %lpad1 

invoke.cont2_before:          ; preds = %invoke.cont 
    store i8* %call, i8** %reduced_var 
    br label %invoke.cont2 

invoke.cont2:          ; preds = %main_block, %invoke.cont2_before 
    %call4 = invoke i32 @_ZStorSt13_Ios_OpenmodeS_(i32 8, i32 16) 
      to label %invoke.cont3_before unwind label %lpad1 

и т.д ...

+0

исправлено, появилась следующая ошибка: у разматывающего устройства нет инструкции для дескриптора! invoke void @ _ZNSt13basic_fstreamIcSt11char_traitsIcEEC1Ev (% "class.std :: basic_ fstream" *% keyStream) LandingPadInst не первая команда, отличная от PHI в блоке. – Denis

+0

Предыдущая ошибка исправлена.Следующий: Блок, содержащий LandingPadInst должен быть подпрыгнут только с помощью разматывающего края вызова . Означает ли это, что я не могу использовать br и touchpad inst вместе? – Denis

+0

Это означает, что BasicBlock, содержащий LandingPadInst, не может быть пунктом BranchInst. Единственный способ перехода на такой BasicBlock - это отключить вызов. –