LLVM IR: функция копирования из одного файла IR LLVM в другой - PullRequest
0 голосов
/ 17 мая 2019

Я пытаюсь скопировать функцию из одного файла в другой. Файл, в который я хотел скопировать функцию, содержит функцию с тем же именем и тем же количеством инструкций. Я решил просто заменить инструкции на другие функции. Я делаю все это в рамках прохода функции.

  1. Я создал проход функции, в котором извлекаю функцию, используя «llvm-extract» из прохода.

  2. Затем я прочитал (.ll) файл, созданный инструментом «llvm-extract», используя:

SMDiagnostic Err;
LLVMContext Context;

std::unique_ptr<Module> ParsedMod(parseIRFile("add.ll", Err, Context));
Module &M = dynamic_cast<Module&>(*ParsedMod);
Module* Mod_ptr = &M;
  1. Затем я прочитал (.ll) файл, в который я хочу скопировать функцию, используя:
std::unique_ptr<Module> ParsedMod2(parseIRFile("server.ll", Err, Context));
Module &M2 = dynamic_cast<Module&>(*ParsedMod2);
Module* Mod_ptr2 = &M2;
  1. У меня есть два итератора, чтобы сохранить точки, с которых я должен начать замену инструкций:
Module::iterator F1;
Module::iterator F2;
  1. Присвойте им значения, чтобы F1 указывал на первую функцию, а F2 на вторую функцию:
    for(Module::iterator func = Mod_ptr->begin(), Lfunc = Mod_ptr->end(); func!=Lfunc; ++func)
        {
          F1 = func;
        }

    for(Module::iterator func2 = Mod_ptr2->begin(), Lfunc2 = Mod_ptr2->end(); func2!=Lfunc2; ++func2)
        {
          if(func2->getName() == F.getName()) //F.getName() gives the same name as the function that was extracted
          {
            F2 = func2;
          }
        }
  1. Замена каждой инструкции F2 инструкцией от F1 с использованием:
    for(Function::iterator bb = F1->begin(), Lbb = F1->end(), bb2 = F2->begin(), Lbb2 = F2->end(); bb2!=Lbb2; ++bb, ++bb2)
        {
          for(BasicBlock::iterator inst = bb->begin(), Linst = bb->end(), inst2 = bb2->begin(), Linst2 = bb2->end(); inst2 != Linst2; ++inst, ++inst2)
          {
            Instruction* I = &*inst;
            Instruction* I2 = &*inst2;

            //errs() << "F1's instruction: " << *I << "\n";
            //errs() << "F2's instruction: " << *I2 << "\n";

            ReplaceInstWithInst(I, I2);
          }
        }

Если я прокомментирую инструкцию ReplaceInstWithInst и раскомментирую инструкции, печатающие инструкции из двух функций, будут напечатаны правильные инструкции.

Я получаю Ошибка сегментации , если я использую инструкцию ReplaceInstWithInst.

1 Ответ

0 голосов
/ 18 мая 2019

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

(Возможно, вы также захотите взглянуть на llvm / lib / Transforms / Utils / CloneFunction.cpp и его вызывающие программы; возможно, вам могут помочь как функции, так и вызывающие.)

...