में तर्क अग्रेषण मुझे कैली (एलएलवीएम-आईआर में) "फॉरवर्डिंग" तर्कों पर कुछ सलाह चाहिए।एलएलवीएम
मान लीजिए कि मेरे पास फ़ंक्शन है जिसे की शुरुआत में सभी मॉड्यूल में अन्य फ़ंक्शंस में कहा जाता है। F
से मुझे अपने तत्काल कॉलर को दिए गए तर्कों को पढ़ने (पढ़ने) की आवश्यकता है।
अभी इस मैं एक struct के अंदर फोन करने वाले के सारे तर्क बॉक्स करते हैं और एक पहचानकर्ता कह जो फोन करने वाले F
से बुलाया जा रहा है के साथ, F
को struct करने के लिए एक i8*
सूचक पारित करने के लिए। F
तब एक विशाल स्विच है जो उपयुक्त अनबॉक्सिंग कोड पर शाखाएं हैं। यह किया जाना चाहिए क्योंकि मॉड्यूल में कार्यों में अलग-अलग हस्ताक्षर होते हैं (भिन्न तर्क/वापसी मूल्य गणना और प्रकार; यहां तक कि अलग-अलग कॉलिंग सम्मेलन), लेकिन यह स्पष्ट रूप से उप-विशिष्ट (प्रदर्शन और कोड आकार बिंदु-दृश्य दोनों से) है क्योंकि मैं ढेर पर संरचना आवंटित करने की आवश्यकता है, इसके अंदर तर्कों की प्रतिलिपि बनाएँ, F
पर एक अतिरिक्त सूचक पास करना और फिर अनबॉक्सिंग करना।
वहाँ एक बेहतर एक समारोह इसके तत्काल फोन करने वाले के ढेर फ्रेम से पहुंचने का एक तरीका यह करने के लिए जिस तरह से, यानी अगर मैं सोच रहा था (यह जानकर, पहचानकर्ता है, जो फोन करने वाले समारोह से बुलाया गया था करने के लिए धन्यवाद) या , सामान्य रूप से, अपने तत्काल कॉलर में मनमानी मान परिभाषित किया गया है। कोई सुझाव?
नोट: मैं जो काम कर रहा हूं उसका पूरा बिंदु एकल फ़ंक्शन F
है जो यह सब करता है; विभाजन/इनलाइनिंग/विशेषज्ञता/टेम्पलेटिंग F
एक विकल्प नहीं है।
स्पष्ट करने के लिए, मान लीजिए हम निम्नलिखित कार्य FuncA
और FuncB
है:
Type1 FuncA(Type2 ArgA1) {
F();
// ...
}
Type3 FuncB(Type4 ArgB1, Type5 ArgB2, Type6 ArgB3) {
F();
// ...
}
(नोट! क्या इस प्रकार सिर्फ छद्म सी-कोड, हमेशा याद रखना हम LLVM-आईआर के बारे में बात कर रहे हैं)
void F() {
switch (caller) {
case FuncA:
// do something with ArgA1
break;
case FuncB:
// do something with ArgB1, ArgB2, ArgB3
break;
}
}
के रूप में मैं पहले भाग में बताया गया है, अभी मेरी 01,232: मैं क्या जरूरत समारोह F
के लिए एक कारगर तरीका निम्न करने के लिए हैइस तरह दिखता है:
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;
}
}
और दो कार्य बन:
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 सीएएफएक्सएक्स के वर्णन के समान ही था। – osgx