2015-07-07 2 views
2

Я пытаюсь выяснить, как выполнить все оптимизации на модуле LLVM (например, все оптимизации -O3). Я пробовал следующее, но я не уверен, что применяются все возможные оптимизации (например, inlining).Оптимизация LLVM с использованием API C++

//take string "llvm" (LLVM IR) and return "output_llvm" (optimized LLVM IR) 
static string optimize(string llvm) { 
    LLVMContext &ctx = getGlobalContext(); 
    SMDiagnostic err; 
    Module *ir = ParseIR(MemoryBuffer::getMemBuffer(llvm), err, ctx); 
    PassManager *pm = new PassManager(); 
    PassManagerBuilder builder; 
    builder.OptLevel = 3; 
    builder.populateModulePassManager(*pm); 
    pm->run(*ir); 
    delete pm; 
    string output_llvm; 
    raw_string_ostream buff(output_llvm); 
    ir->print(buff, NULL); 
    return output_llvm; 
} 

Есть ли что-нибудь еще, что я могу сделать, чтобы улучшить производительность выходного LLVM IR?

EDIT: Я пытался добавить все оптимизаций из функции AddOptimizationPasses() в opt.cpp, как показано ниже:

PassManager *pm = new PassManager(); 
int optLevel = 3; 
int sizeLevel = 0; 
PassManagerBuilder builder; 
builder.OptLevel = optLevel; 
builder.SizeLevel = sizeLevel; 
builder.Inliner = createFunctionInliningPass(optLevel, sizeLevel); 
builder.DisableUnitAtATime = false; 
builder.DisableUnrollLoops = false; 
builder.LoopVectorize = true; 
builder.SLPVectorize = true; 
builder.populateModulePassManager(*pm); 
pm->run(*module); 

Кроме того, я создаю FunctionPassManager, прежде чем я создаю PassManager и добавить несколько проходов как так:

FunctionPassManager *fpm = new FunctionPassManager(module); 
// add several passes 
fpm->doInitialization(); 
for (Function &f : *ir) 
    fpm->run(f); 
fpm->doFinalization(); 

Однако производительность такая же, как работает в командной строке с -O1 в то время как я могу получить гораздо более высокую производительность на командной строки с использованием -O3. Какие-либо предложения?

ответ

4

Следуйте логике в функции AddOptimizationPasses в opt.cpp. Это источник истины.

+0

Спасибо, я попробовал ваше предложение, но, к сожалению, у меня проблемы. Я отредактировал вопрос соответствующим образом. – agg212

+0

Вы можете попросить распечатать все пропуски, которые он запускает. Включите это же для своего настраиваемого драйвера. Сравните, чтобы увидеть, какие пропуски не запускаются в вашем драйвере, но выполняются с помощью 'opt -O3' –

+0

. Каков вариант, который вы передаете' opt', чтобы распечатать имена пропусков, которые он запускает? –

0

При изучении оптимизации LLVM я нашел this information on pass ordering, и я думаю, что это потенциально говорит, почему кто-то может столкнуться с этой ситуацией.

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

Учитывая конкретную формулировку здесь и тот факт, что ответ Эли был принят, я не уверен на 100%, если это то, что наблюдал ОП, но это знание может быть полезно для других с похожими вопросами, которые находят этот ответ так, как я ,