LLVM преобразовывает константу в значение
Я использую пользовательский проход LLVM, где, если я сталкиваюсь с хранилищем, куда компилятор преобразует значение в константу; например, есть явное хранилище:
X[gidx] = 10;
Тогда LLVM сгенерирует эту ошибку:
aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
Порядок наследования выглядит следующим образом: Value<-User <-Constant, поэтому это не должно быть проблемой, но это так. Использование приведения к ConstantInt или ConstantFP не влияет на эту ошибку. Итак, я попробовал это раздутое решение:
Value *new_value;
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){
Instruction *allocInst = builder.CreateAlloca(old_value->getType());
builder.CreateStore(old_value, allocInst);
new_value = builder.CreateLoad(allocResultInst);
}
Тем не менее, это решение создает свои собственные ошибки реестра, когда речь идет о другом типе, поэтому я бы хотел этого избежать.
Кто-нибудь знает, как преобразовать константу в значение? Это должна быть простая проблема, которую я не вижу. Я работаю на ядрах Ubuntu 12.04, LLVM 3, AMD GPU, OpenCL.
Спасибо заранее
РЕДАКТИРОВАТЬ:
Исходный код, который производит первую из перечисленных ошибок, просто:
builder.CreateStore(old_value, store_addr);
EDIT2:
Это old_value объявлено как Value *old_value = current_instruction->getOperand(0);
Поэтому я беру значение, которое нужно сохранить, в данном случае "10" из первой строки кода.
1 ответ
Вы не предоставили код, вызвавший это первое утверждение, но его формулировка довольно ясна: вы пытаетесь создать хранилище, в котором операнд значения и операнд указателя не согласуются по своим типам. Было бы полезно, если бы вы предоставили код, который сгенерировал эту ошибку.
Ваше второе, так называемое "раздутое" решение, является правильным способом хранения old_value
в стек, а затем загрузите его снова. Ты пишешь:
Однако это решение создает свои собственные ошибки регистра, когда задействованы разные типы
Эти "ошибки регистрации" - реальная проблема, к которой вы должны обратиться.
В любом случае вся предпосылка "преобразования константы в значение" ошибочна - как вы правильно заметили, все константы являются значениями. Нет смысла сохранять значение в стеке с единственной целью его повторной загрузки, и действительно, стандартный проход LLVM "mem2reg" полностью удалит такую последовательность, заменив все виды использования нагрузки исходным значением.