"İletim" argümanlarının bir arayana (LLVM-IR'de) ilişkin bazı önerilere ihtiyacım var.Bağımsız değişken iletme LLVM
Bir modülde tüm diğer işlevlerinin başında çağrılan bir işlev var F
varsayalım. F
'dan derhal arayana iletilen argümanlara erişmem gerekiyor. Şu anda
F
gelen çağrılan bir tanımlayıcı anlatma yanında
F
için yapı için bir
i8*
işaretçi geçmek.
F
, daha sonra uygun kutulama koduna giden dev bir anahtara sahip. Bu, modüldeki işlevlerin farklı imzalara (farklı argüman/dönüş değeri sayısı ve türleri; farklı arama kuralları bile) sahip olduğu için yapılmalıdır, ancak açıkçası (hem performanstan hem de kod boyutunda bir bakış açısından) düşüktür. Yapının yığında ayrılması, içindeki argümanların kopyalanması,
F
'a ek bir işaretçinin iletilmesi ve sonra kutunun çıkarılması gerekir.
yani yapmak için daha iyi bir yolu, bir fonksiyonun onun hemen arayanın yığın çerçevesi erişmek için bir yol ise I (, işlev çağrılabilir arayan taraf tanımlayıcısı, sayesinde bilerek) merak veya Genel olarak numaralı telefon hattında tanımlanmış keyfi değerler. Baska öneri?
not: üzerinde çalıştıklarımın tüm noktası, tek işlevi olan F
işlevini yerine getirmektedir; bölme/satır içi/özelleştirme/şablonlama F
bir seçenek değil. netleştirmek için
, biz FuncA
ve FuncB
aşağıdaki işlevleri olduğunu varsayalım:
Type1 FuncA(Type2 ArgA1) {
F();
// ...
}
Type3 FuncB(Type4 ArgB1, Type5 ArgB2, Type6 ArgB3) {
F();
// ...
}
(not! ne şu sadece sözde-C-kodu, her zaman LLVM-IR bahsediyoruz hatırlıyorum olan)
void F() {
switch (caller) {
case FuncA:
// do something with ArgA1
break;
case FuncB:
// do something with ArgB1, ArgB2, ArgB3
break;
}
}
ben ilk bölümde açıklandığı gibi, şu anda benim: ne gerek aşağıdakileri yapmak fonksiyonu F
için etkili bir yoldur
struct Args_FuncA { Type2 ArgA1 };
struct Args_FuncB { Type4 ArgB1, Type5 ArgB2, Type6 ArgB3 };
void F(int callerID, void *args) {
switch (callerID) {
case ID_FuncA:
Args_FuncA *ArgsFuncA = (Args_FuncA*)args;
Type2 ArgA1 = ArgsFuncA->ArgA1;
// do something with ArgA1
break;
case ID_FuncB:
Args_FuncB *ArgsFuncB = (Args_FuncB*)args;
Type4 ArgB1 = ArgsFuncB->ArgB1;
Type5 ArgB2 = ArgsFuncB->ArgB2;
Type6 ArgB3 = ArgsFuncB->ArgB3;
// do something with ArgB1, ArgB2, ArgB3
break;
}
}
ve iki işlev haline:şöyle bunu doğru
Type1 FuncA(Type2 ArgA1) {
Args_FuncA args = { ArgA1 };
F(ID_FuncA, (void*)&args);
// ...
}
Type3 FuncB(Type4 ArgB1, Type5 ArgB2, Type6 ArgB3) {
Args_FuncB args = { ArgB1, ArgB2, ArgB3 };
F(ID_FuncB, (void*)&args);
// ...
}
DTrace çok aynısını yaptı. – osgx