Я абсолютный новичок, пытающийся обмануть изменение генерации ИК. Я надеюсь, что этот вопрос достаточно точен, чтобы отвечать. Если нет, пожалуйста, дайте мне знать, что я мог бы добавить, чтобы помочь.
Мой вариант использования - изменить генерацию IR для ключевого слова "for". Моя цель состоит в том, чтобы создать второй alloca для переменной цикла в теле цикла, чтобы я мог выполнить некоторые преобразования в нем. Второе выделение должно быть в теле цикла, чтобы было динамическое распределение. Новая переменная не может быть в блоке ввода. Я дошел до момента генерации необходимого второго alloca (%ZZZZ
, в блоке forall.detach
ниже). IR выглядит следующим образом (с удаленными несущественными вещами):
entry:
%i = alloca i32, align 4
store i32 17, i32* %i, align 4
br label %forall.cond
forall.cond: ; preds = %forall.inc, %entry
%0 = load i32, i32* %i, align 4
%cmp = icmp slt i32 %0, 25
br i1 %cmp, label %forall.detach, label %forall.sync
forall.detach: ; preds = %forall.cond
%ZZZZ = alloca i32
%1 = load i32, i32* %i, align 4
store i32 %1, i32* %ZZZZ, align 4
br label %forall.body
forall.body: ; preds = %forall.detach
%2 = load i32, i32* %i, align 4
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %2)
br label %forall.reattach
Я использую следующий c ++ api для генерации %ZZZZ
alloca и сохранения в нем %i
(кстати, если есть более простой)или один шаг API, я бы тоже хотел это знать):
const DeclStmt *DS = cast<DeclStmt>(S.getInit());
const VarDecl *LoopVar = cast<VarDecl>(DS->getSingleDecl());
QualType RefType = LoopVar->getType();
llvm::Type *LReduceType = getTypes().ConvertType(RefType);
llvm::AllocaInst *RInst = Builder.CreateAlloca(LReduceType, nullptr, "ZZZZ");
Address RVarAddr = Address(RInst, getContext().getTypeAlignInChars(RefType));
Address OuterLoopAddr = GetAddrOfLocalVar(LoopVar);
llvm::Value *OuterLoopVal = Builder.CreateLoad(OuterLoopAddr);
// llvm::Value *RZero = llvm::ConstantInt::get(ConvertType(RefType), 0);
Builder.CreateStore(OuterLoopVal, RVarAddr);
Вопрос прост. В ИК у меня есть следующая строка в forall.body
основном блоке:
%2 = load i32, i32* %i, align 4
, и я хотел бы изменить это на:
%2 = load i32, i32* %ZZZZ, align 4
, но я не знаю, как,На самом деле я не могу найти таких примеров в Интернете. Мне известна функция API ReplaceAllUsesWith
, но я не могу понять, как ее использовать или что-то еще, что эквивалентно. Если кто-то может предложить какие-либо предложения о том, как реализовать эту подстановку переменных, это будет оценено.
спасибо, Дэнни