2. LLVM Language Reference Manual - identifiers (shortened) (1157487), страница 2
Текст из файла (страница 2)
Интерпретация каждого индекса зависит отиндексируемого типа. Первый индексотносится к указателю,переданному первым аргументом, второй индекс к значению на котороеуказывает указатель (не обязательно, чтобы значение адресовалосьнапрямую, поскольку первый индекс может быть не нулевым).
Первыйиндексируемый тип должен быть указателем, последующие могут быть:array, vector, struct. Примечание: последующие индексируемые типы немогут быть указателями, поскольку тогда потребовалось бы загружатьуказатель, перед продолжением вычислений.Рассмотрим пример:struct RT {char A;int B[10][20];char C;};struct ST {int X;double Y;struct RT Z;};int *foo(struct ST *s) {return &s[1].Z.B[5][13];}Код LLVM:%struct.RT = type { i8, [10 x [20 x i32]], i8 }%struct.ST = type { i32, double, %struct.RT }define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {entry:%arrayidx = getelementptr inbounds %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13ret i32* %arrayidx}В примере выше первый индекс относится ктипу „%struct.ST*„,являющейся указателем на структуру „%struct.ST„ = „{ i32, double,%struct.RT }„.
Второй индекс относится к третьему элементу структуры „%struct.RT„ = „{ i8 , [10 x [20 x i32]], i8 }„, другой структуре. Третийиндекс относится ко второму элементу структуры - „[10 x [20 x i32]]„,массиву. Двумерный массив состоит из элементов „i32„ . Инструкция The„getelementptr„возвращает указатель на этот элемент, поэтомувозвращаемое значение имеет тип „i32*„.Тоже самое можно записать в несколько инструкций:define i32* @foo(%struct.ST* %s) {%t1 = getelementptr %struct.ST* %s, i32 1; %struct.ST*:%t1%t2 = getelementptr %struct.ST* %t1, i32 0, i32 2; %struct.RT*:%t2%t3 = getelementptr %struct.RT* %t2, i32 0, i32 1; [10 x [20 x i32]]*:%t3%t4 = getelementptr [10 x [20 x i32]]* %t3, i32 0, i32 5 ; [20 x i32]*:%t4%t5 = getelementptr [20 x i32]* %t4, i32 0, i32 13; i32*:%t5ret i32* %t5}other instructions‘icmp‘Инструкция возвращает булево значение, являющееся результатомсравнения.<результат > = icmp <условие> <тип> <операнд1>, <операнд2>Первый операнд является условием сравниения:eq: равноne: не равноugt: беззнаковое большеuge: беззнаковое больше или равноult: беззнаковое меньшеule: беззнаковое меньше или равноsgt: знаковое большеsge: знаковое больше или равноslt: знаковое меньшеsle: знаковое меньше или равноПример:<result> = icmp eq i32 4, 5; result=false‘phi‘Инструкция „phi„ используется для реализации φ-узла в представленииSSA.<результат> = phi <тип> [ <значение0>, <метка0>], ...Пример:Loop:%indvar = phi i32 [ 0, %LoopHeader ], [ %nextindvar, %Loop ]%nextindvar = add i32 %indvar, 1br label %Loop'call'Инструкция 'call' представляет собой обычный вызов функции.conversion operations'sext'Инструкция 'sext' расширяет значение до типа ty2.<результат> = sext <тип1> <значение> to <тип2>Пример:%x = sext i8 -1 to i16.