Ошибка: X86CodeEmitter LLVM

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

pseudo instructions should be removed before code emission
UNREACHABLE executed at /home/leonor/llvm/llvm/lib/Target/X86/X86CodeEmitter.cpp:1164!
Stack dump:
0.  Running pass 'X86 Machine Code Emitter' on function '@main'
./build/Release+Asserts/bin/llvm-dis: Bitcode stream must be at least 16 bytes in length

Моя программа принимает в качестве входных данных файл .bc, а затем загружает файл и показывает его. Я сомневаюсь: почему эта ошибка возникает только тогда, когда программа C содержит условные операторы (if, for ..). Как решить??

Мой код:

int main(int argc, char **argv) {

  InitializeNativeTarget();
  LLVMContext &Context = getGlobalContext();
  std::string Err;
  const std::string InputFile = "teste_f1.bc"; 
  OwningPtr<MemoryBuffer> result;
  error_code ec = MemoryBuffer::getFile(InputFile, result);
  MemoryBuffer *buffer = result.take();
  Module * Mod = ParseBitcodeFile(buffer, Context);

  ExecutionEngine* EE = 0;
  EngineBuilder builder(Mod);
  builder.setErrorStr(&Err);
  builder.setEngineKind(EngineKind::JIT);   
  EE = builder.create();

  Function * func = Mod->getFunction("main");
  std::vector <std::string> params;
  params.push_back(Mod->getModuleIdentifier());

  EE->runStaticConstructorsDestructors(false);
  int Result = EE->runFunctionAsMain(func, params, NULL);
  EE->runStaticConstructorsDestructors(true);

  WriteBitcodeToFile(Mod, outs());

  delete Mod;
  return 0;

}

person user2084755    schedule 17.08.2013    source источник
comment
Моя программа принимает в качестве входных данных файл .bc, а затем загружает файл и показывает его - ну, это не то, что делает код. Код загружает файл .bc, выполняет функцию main внутри, а затем возвращает содержимое файла .bc (который является двоичным) на выход. И проблема возникает во время выполнения (точнее, JIT-компиляции). Кстати, если вы последуете этому с помощью llvm-dis, вы можете просто вместо этого вызвать print или dump в модуле, чтобы получить текстовое представление.   -  person Oak    schedule 18.08.2013


Ответы (1)


Это связано с тем, что код, содержащий условные операторы (if, for и т. д.), приводит к IR, содержащему phi узлов. Вы можете удалить узлы phi, используя проход reg2mem. Команда будет:

opt -reg2mem -o output.bc input.bc
person shrm    schedule 17.08.2013
comment
Проход reg2mem добавляет узлы phi, а не удаляет их (путем замены загрузки и сохранения на phi). Также я не понимаю, почему наличие phi-узлов должно приводить к тому, что эмиттер кода x86 не работает... - person Oak; 18.08.2013
comment
@Oak reg2mem не добавляет фи-узлы, взгляните на следующие ссылки из списков рассылки llvm. Если вы все еще не уверены, попробуйте сами на фрагменте кода. Как вы думаете, как машина будет выполнять phi-узел в сборке? Почему эмиттер кода будет генерировать фи-узлы, если машина не может выполнять фи-узлы? Ссылки: llvm.1065342.n5.nabble.com/PHI-nodes- td2116.html и groups.google.com/forum/ #!topic/llvm-dev/UMaYSqdT014 - person shrm; 18.08.2013
comment
моя ошибка; Я прочитал reg2mem как mem2reg :) Но я все еще не понимаю часть фи-узлов и испускаемый код. LLVM IR действительно не является сборкой x86, поэтому есть понижение и выбор инструкций, которые должны заботиться о фи-узлах. - person Oak; 18.08.2013
comment
@Oak OP сталкивается с ошибкой на x86CodeEmitter, а не на ИК-излучателе LLVM. Существует проход машинной функции под названием PHIelimination, что означает, что узлы phi опускаются до сборки, но, тем не менее, должны быть удалены до того, как будет сгенерирован окончательный код. Что касается того, почему phi-узлы распространяются до сборки, это хороший вопрос, возможно, потому, что от этого зависят некоторые проходы машинного уровня. Попробуйте исправить свою ошибку, проголосовав за. - person shrm; 18.08.2013