2017-01-18 7 views
2

Я хочу разобрать IR-файл, созданный с помощью clang++ -S -emit-llvm test.cpp -o test.ir, с помощью вызова parseIRFile, немного манипулировать этим IR, а затем записать IR обратно в файл.LLVM: Как записать IR в файл и запустить его?

Я пробовал использовать вызов WriteBitcodeToFile, но это не работает должным образом.

Как бы написать модуль обратно в ИК-порт, а затем скомпилировать и запустить измененный ИК-порт?

#include <llvm/IR/Module.h> 
#include <llvm/IRReader/IRReader.h> 
#include <llvm/IR/LLVMContext.h> 
#include <llvm/Support/SourceMgr.h> 
#include <llvm/Bitcode/ReaderWriter.h> 
#include <llvm/Support/FileSystem.h> 

using namespace llvm; 
int main() 
{ 
    LLVMContext context; 
    SMDiagnostic error; 
    std::unique_ptr<Module> m = parseIRFile("test.ir", error, context); 

    std::error_code EC; 
    llvm::raw_fd_ostream OS("module", EC, llvm::sys::fs::F_None); 
    WriteBitcodeToFile(m.get(), OS); 
    OS.flush(); 

    return 0; 
} 
+0

Что вы имеете в виду под "не работает, как ожидалось"? – Steeve

+0

Когда я открываю файл, содержимое кажется двоичным? – Shuzheng

+0

@Shuzheng Это всего лишь двоичное кодирование IR. Вы можете использовать 'llvm-dis' для получения текстового IR, но вы должны иметь возможность использовать' llc' непосредственно в двоичном файле для создания объектного файла. – TartanLlama

ответ

1

IR не является удобочитаемым человеком. Вы можете использовать llvm-dis, чтобы преобразовать его в человеческую версию, например, @TartanLlama. Вы можете запустить биткод с помощью команды lli. После изменения IR вы увидите, что ваш измененный ИК-режим работает с lli.

+0

IR читается человеком? Похоже, сборка x86, на мой взгляд, с такими заявлениями, как alloca, store и ret? – Shuzheng

+0

Они говорили о биткоде, обычно 'IR' для представления памяти. – Joky

+0

Это некрасиво, но LLVM IR и даже Assembly являются «удобочитаемыми» после привыкания к нему. Представление битового кода - это еще одна история. – Silverclaw

2

Самый простой способ сделать это демпинг свой модуль на стандартный вывод с помощью:

m->dump(); 

Затем вы можете перенаправить вывод программы ++ ваш C в текстовый файл и скомпилировать его с помощью ООО:

llc <sample_module.ll> sample_module.s 

Вы также можете использовать функцию печати:

void print (raw_ostream &OS, AssemblyAnnotationWriter *AAW, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const 
0

Вам нужно написать пропуск LLVM, который позволяет вам проходить через функцию Function по функции/модулю по модулю и читать/изменять/записывать на нее. Вы можете запустить этот проход в файле байт-кода с помощью команды opt, и он вернет измененный файл байт-кода, который вы можете использовать.

Вот некоторые источники для написания пропуска:

1) http://llvm.org/docs/WritingAnLLVMPass.html

2) https://www.cs.cornell.edu/~asampson/blog/llvm.html

+0

Будет ли команда opt возвращать файл bitcode с вставленными инструкциями и т. Д.? Это происходит автоматически, если я вставляю инструкции в базовый блок? – Shuzheng

+0

Да, если вы пишете свой LLVM-проход таким образом, чтобы он вставлял инструкцию в байт-код LLVM, тогда запуск этого прохода с помощью '' 'opt''' возвращает измененный байт-код. Здесь '' 'opt''' используется только для запуска вашего байта на байт-код. Например, просмотрите раздел под заголовком «Now Make the Pass Do Something Interesting» на этой странице - https://www.cs.cornell.edu/~asampson/blog/llvm.html.Здесь этот пример заменяет операцию '' '' '' '' '' '' '', используя пропуск модуля. – deLta

+0

Вы также можете использовать '' 'clang''' для запуска прохода с помощью комбинации -Xclang и -load flags – deLta