を手に持っていますType*
。そのサイズ (このタイプのオブジェクトがメモリ内で占めるサイズ) をビット / バイト単位で調べるにはどうすればよいでしょうか? 「プリミティブ」または「スカラー」サイズを取得できるさまざまな方法がありますが、集約型の場合は役に立ちません...
ベストアンサー1
もし、あんたがのみIRに挿入するためサイズが必要な場合(たとえば、呼び出しに送ることができるためmalloc()
)、getelementptr
命令を使用して(少しキャストして)面倒な作業を行うことができます。ここで説明(最新の LLVM に更新):
LLVM には特別な目的
sizeof
/offsetof
命令は含まれていませんが、getelementptr
命令を使用してこれらの値を評価できます。基本的な考え方は、ポインターgetelementptr
を使用してnull
、必要な値を計算することです。getelementptr
ポインターとして値を生成するため、結果は使用前に整数にキャストされます。たとえば、ある型のサイズを取得するには
%T
、次のようなものを使用します。%Size = getelementptr %T* null, i32 1 %SizeI = ptrtoint %T* %Size to i32
T
このコードは、ポインターから始まる要素の配列があるかのように見せかけていますnull
。配列内の 2 番目の要素 (要素 #1) へのポインターを取得し、それを整数として扱います。これにより、1 つの要素T
のサイズが計算されます。T
これを実行する利点は、値が何であるかを気にしていない場合、つまり IR から正しい値を何かに渡す必要がある場合に、まさにこれが役立つことです。これは、sizeof()
IR 生成で -alike 操作が必要になる最も一般的なケースです。
このページでは、同等のことを実行する方法についても説明していますoffsetof()
。
構造体内のフィールドのオフセットを取得するには、同様のトリックが使用されます。たとえば、
{ i8, i32* }
(ポインターのターゲット アライメント要件に応じて) の 2 番目の要素 (要素 #1) のアドレスを取得するには、次のようなものを使用する必要があります。%Offset = getelementptr {i8,i32*}* null, i32 0, i32 1 %OffsetI = ptrtoint i32** %Offset to i32
これはトリックと同じように機能します
sizeof
。つまり、ポインターに型のインスタンスがあるものと仮定しnull
、関心のあるフィールドのアドレスを取得します。このアドレスはフィールドのオフセットです。どちらの場合も、式はコード生成時に定数に評価されるため、この手法を使用しても実行時のオーバーヘッドは発生しないことに注意してください。
IR オプティマイザーは値を定数に変換します。