2015-03-18 3 views
2

Я пытаюсь понять инструкцию getelementptr в llvm IR, но не полностью ее понимаю.Приращение ptr в llvm ir

У меня есть структура, как показано ниже -

struct Foo { 
    int32_t* p; 
} 

Я хочу, чтобы это сделать -

foo.p++; 

Что бы правильный код для этого?

%0 = getelementptr %Foo* %fooPtr, i32 0, i32 0 
%1 = getelementptr i32* %0, i8 1 
store i32* %1, i32* %0 

Мне интересно, нужно ли сначала загружать значение в% 0 с использованием «нагрузки» перед выполнением 2-й строки.

Спасибо!

ответ

2

Вы можете видеть инструкцию GEP как операцию, выполняющую арифметические операции с указателями. В LLVM IR команда GEP является вашей инструкцией по выбору для выполнения операций с указателями. Вам не нужно делать громоздкие вычисления размера ваших типов и смещений для ручного выполнения таких операций.

В вашем случае:

%0 = getelementptr %Foo* %fooPtr, i32 0, i32 0 

выбирает элемент внутри структуры. Он использует указатель operatand %fooPtr для расчета %0 = ((fooPtr + 0) + 0). GEP не знает о том, что fooPtr просто указывает на один элемент Foo, поэтому для выбора члена используются два индекса.

%1 = getelementptr i32* %0, i8 1 

Как упоминалось выше ПГЭ выполняет арифметические операции над указателями и в вашем случае получить %1 = (p + 1);

Поскольку вы работаете на указатели с помощью GEP вам не нужно, чтобы загрузить значение р. GEP сделает это неявно для вас.

Теперь вы можете сохранить новый индекс обратно в позицию члена p внутри структуры Foo, на которую указывает fooPtr.

Для дальнейшего чтения: The Often Misunderstood GEP Instruction

+0

Я прочитал этот документ, и я хочу, чтобы повторить свое понимание, чтобы убедиться, что я получил это - «первое числовое значение после того, как PTR аргумент делает неявное разыменования указателя и добавляет это номер к нему ... Последующие числа просто смещаются к адресу памяти, и они не вызывают разыменования .. "... Это правильно? – user855

Смежные вопросы