Как заменить переменные на ReplaceAllUsesWith или аналогичные? - PullRequest
0 голосов
/ 09 ноября 2019

Я абсолютный новичок, пытающийся обмануть изменение генерации ИК. Я надеюсь, что этот вопрос достаточно точен, чтобы отвечать. Если нет, пожалуйста, дайте мне знать, что я мог бы добавить, чтобы помочь.

Мой вариант использования - изменить генерацию 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, но я не могу понять, как ее использовать или что-то еще, что эквивалентно. Если кто-то может предложить какие-либо предложения о том, как реализовать эту подстановку переменных, это будет оценено.

спасибо, Дэнни

...