2010-08-12 24 views
3

Je crée un petit langage très similaire à hlsl mais qui ne prend en charge que les pixel shaders. Ce langage utilise reflection.emit pour créer des assemblys de point net qui implémentent la même fonctionnalité. Je suis actuellement en train de tester mon implémentation de l'instruction de branchement "if" et dans un de mes tests unitaires (un si grand avec inner if else) a échoué avec le message d'erreur suivant:Erreur avec les opcodes de forme courte dans Reflection.Emit

System.NotSupportedException: Branche d'un octet illégale à la position: 32. Branche demandée était: 132.

Je ai tracé le problème à l'utilisation d'instructions de forme abrégée dans mon cas OpCodes.Br_S. La solution était simple, j'ai remplacé OpCodes.Br_S avec OpCodes.Br cependant j'ai quelques questions sur cette solution:

Cette solution a un impact sur la performance du code généré? Si je veux générer correctement Br_S pour un seul octet et Br pour les autres cas, comment puis-je faire cela? Le problème ici est que j'utilise un modèle de visiteur et pour une instruction de branche comme le "si" je dois d'abord produire Br ou Br_s et à ce moment je n'ai aucun moyen de savoir si le code restant nécessitera plus d'un octet pour sauter à l'étiquette. Pour mieux illustrer ma question c'est le code que je produis pour les déclarations suivantes:

Ma langue:

int a = -1; if (1>1) { a=1; } else if(2>2) { a=2; }

IL:

.method public virtual final instance int32 Main() cil managed {

.maxstack 4 
.locals init (
    [0] int32 num) 
L_0000: ldc.i4.m1 
L_0001: stloc.0 
L_0002: ldc.i4.1 
L_0003: ldc.i4.1 
L_0004: ble.s L_000a 
L_0006: ldc.i4.1 
L_0007: stloc.0 
L_0008: br.s L_0010 
L_000a: ldc.i4.2 
L_000b: ldc.i4.2 
L_000c: ble.s L_0010 
L_000e: ldc.i4.2 
L_000f: stloc.0 
L_0010: ldloc.0 
L_0011: ret 

}

Dans ce cas, je suis en utilisant deux instructions de forme courte, ble.s et br.s, pour implémenter les ifs exactement comme le fait le compilateur .net. Cependant compilateur .NET est capable de choisir br.s ou br selon les cas, mon problème est comment puis-je faire quelque chose de similaire?

tnks

+3

Votre IL est un peu plus grand, pas grave. Faites confiance au compilateur JIT pour avoir raison. Ces micro optimisations ne valent pas votre temps. –

+0

Je voudrais le faire mais j'ai besoin de générer l'IL moi-même car il n'y a pas de compilateur C# dans silverlight par exemple. Je voudrais utiliser cela dans Silverlight et aussi dans d'autres environnements qui n'ont pas de compilateur disponible ... –

+0

Je crois que Hans suggère que vous ne vous souciez pas de la forme courte (avec laquelle vous rencontrez un problème) et utilisez le Longue forme standard puisque cette optimisation se fera automatiquement avec le JIT (que Silverlight a, tout comme n'importe quel autre CLR impl) –

Répondre

6

Si vous voulez faire cela, vous devrez calculer le décalage vers la cible de branche avant de générer la branche elle-même, puis déterminer si le décalage est assez petit pour être atteint par la forme courte instruction. Je ne pense pas qu'il existe un moyen particulièrement facile de le faire en utilisant la bibliothèque Reflection.Emit.

+0

S'il vous plaît, je suis intéressé à comprendre cette réponse. J'ai un problème similaire. De quoi parles-tu? Pouvez-vous expliquer avec une sorte d'illustration. Vous pouvez également me diriger vers d'autres ressources dont je peux bénéficier. Merci d'avance. – Tebo

+2

@ColourBlend - Les instructions de branchement ont une cible, spécifiée comme un offset dans le code IL, même si l'API 'ILGenerator' vous laisse simplement passer une étiquette (et le framework calcule le décalage approprié en fonction de l'emplacement du label) . 'Br_S' (et d'autres instructions courtes) exigent que le décalage puisse tenir dans un octet (c'est-à-dire, un décalage de pas plus de 127 octets dans le flux d'instructions). Est ce que ça aide? – kvb

+0

Merci. C'était utile. J'ai examiné un peu avant de répondre. Est-ce qu'un DynamicMethod s'exécute plus vite que sa méthode statique équivalente (méthodes de conception)? La traduction d'une méthode de conception dans MSIL améliorera-t-elle les performances? – Tebo