J'ai été vérifier entier-gmp code source pour comprendre comment les étrangers primops peuvent être mises en œuvre en termes de cmm comme documenté sur GHC Primops page. Je suis conscient de techniques à mettre en œuvre en utilisant llvm hack ou fvia-C/gcc - c'est plus une expérience d'apprentissage pour moi de comprendre cette troisième approche qui entier-librairie gmp utilise.
Donc, j'ai regardé CMM tutoriel sur MSFT page (lien pdf), est passé par de GHC CMM page, et il y a encore des questions sans réponse (difficile de garder tous ces concepts dans la tête sans creuser la CMM, qui est ce que je fais maintenant). Il y a ce fragment de code d' entier-bmp cmm fichier:
integer_cmm_int2Integerzh (W_ val)
{
W_ s, p; /* to avoid aliasing */
ALLOC_PRIM_N (SIZEOF_StgArrWords + WDS(1), integer_cmm_int2Integerzh, val);
p = Hp - SIZEOF_StgArrWords;
SET_HDR(p, stg_ARR_WORDS_info, CCCS);
StgArrWords_bytes(p) = SIZEOF_W;
/* mpz_set_si is inlined here, makes things simpler */
if (%lt(val,0)) {
s = -1;
Hp(0) = -val;
} else {
if (%gt(val,0)) {
s = 1;
Hp(0) = val;
} else {
s = 0;
}
}
/* returns (# size :: Int#,
data :: ByteArray#
#)
*/
return (s,p);
}
Tel que défini dans ghc cmm en-tête:
W_ is alias for word.
ALLOC_PRIM_N is a function for allocating memory on the heap for primitive object.
Sp(n) and Hp(n) are defined as below (comments are mine):
#define WDS(n) ((n)*SIZEOF_W) //WDS(n) calculates n*sizeof(Word)
#define Sp(n) W_[Sp + WDS(n)]//Sp(n) points to Stackpointer + n word offset?
#define Hp(n) W_[Hp + WDS(n)]//Hp(n) points to Heap pointer + n word offset?
Je ne comprends pas les lignes 5-9 (ligne 1 est le départ, dans le cas où vous avez 1/0 confusion). Plus précisément:
- Pourquoi l'appel de la fonction format de ALLOC_PRIM_N (octets,amusant,arg) de cette façon?
- Pourquoi est p manipulé de cette façon?
La fonction de ce que je comprends (à partir de la recherche à la signature de fonction en Prim.hs) prend un entier et retourne un int, tableau d'octets) (stocké dans s
,p
respectivement dans le code).
Pour toute personne qui s'interroge sur inline appel en if block
, il est de la cmm mise en œuvre des bpf mpz_init_si fonction. Ma conjecture est que si vous appelez une fonction définie dans le fichier de l'objet à travers ccall, il ne peut pas être incorporé (ce qui est logique puisque c'est l'objet du code, pas de code intermédiaire - LLVM approche semble plus adapté pour inline par LLVM IR). Ainsi, l'optimisation a été de définir un cmm de la représentation de la fonction inline. S'il vous plaît corrigez-moi si cette conjecture est fausse.
Explication de lignes 5-9 sera très apprécié. J'ai d'autres questions sur d'autres macros définies en entier-gmp fichier, mais c'est peut être trop demander à un poste. Si vous pouvez répondre à la question avec un Haskell page wiki ou un blog (vous pouvez poster le lien de réponse), ce serait très apprécié (et si vous le faites, je voudrais également apprécier étape-par-étape de plain-pied par le biais d'un entier-gmp cmm macro comme GMP_TAKE2_RET1
).