এলএলভিএম কেন একটি অতিরিক্ত কাজ করতে পারে?


9

এখানে এনাম সংজ্ঞা এবং একটি mainফাংশন সহ একটি সাধারণ সি ফাইল রয়েছে :

enum days {MON, TUE, WED, THU};

int main() {
    enum days d;
    d = WED;
    return 0;
}

এটি নিম্নলিখিত এলএলভিএম আইআর স্থানান্তর করে:

define dso_local i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  store i32 2, i32* %2, align 4
  ret i32 0
}

%2স্পষ্টতই dপরিবর্তনশীল, যা এটি 2 প্রদান করে। %1শূন্যটি সরাসরি ফিরে আসলে কী মিলবে ?


1
আপনি এই আইআর তৈরি করতে কোন পতাকা ব্যবহার করেছেন?
১১

@ অ্যারোড, আমি সর্বশেষতম স্থিতিশীল এলএলভিএম স্যুটটি ইনস্টল করেছি এবং দৌড়েছিclang-9 -S -emit-llvm simple.c
ম্যাকলেগিন

1
আমি মনে করি main( গডবোল্ট.আর্গ / জেড / কেইটিএস- গুলি ) এর আগে ইনিশিয়ালেশনের সাথে কিছু করার আছে । লিঙ্কটি দেখায় যে কীভাবে সমাবেশটি উত্সটিতে ম্যাপ করা হয়েছে
প্রদীপ কুমার

2
@ প্রদীপ কুমার: প্রকৃতপক্ষে, আপনি যদি ফাংশনটির নাম বাদে অন্য কোনও কিছুতে mainপরিবর্তন করেন তবে রহস্যজনক অতিরিক্ত পরিবর্তনশীল অদৃশ্য হয়ে যায়। মজার বিষয় হল, আপনি returnবিবৃতি সম্পূর্ণরূপে বাদ দিলে এটিও অদৃশ্য হয়ে যায় (যা mainসি এর জন্য বৈধ এবং সমতুল্য return 0;)।
নাট এল্ডারেজ

1
@ ম্যাকলজিন: আমি এতটা নিশ্চিত নই। যদি আপনি ঘোষণা mainকরেন যে int main(int argc, char **argv)আপনি দেখতে argcএবং argvস্ট্যাকের অনুলিপি করেছেন, তবে রহস্যজনক শূন্য ভেরিয়েবলটি এগুলি ছাড়াও এখনও রয়েছে।
নাট এল্ডারেজ

উত্তর:


3

কোনও ফাংশনে একাধিক রিটার্নের স্টেটমেন্টগুলি হ্যান্ডেল%1 করার জন্য এই রেজিস্টারটি ঝাঁকুনির দ্বারা উত্পন্ন হয়েছিল । কোনও পূর্ণসংখ্যার ফ্যাক্টরিয়াল গণনা করার জন্য আপনার কোনও ফাংশন রয়েছে তা কল্পনা করুন। পরিবর্তে এটি লিখতে

int factorial(int n){
    int result;
    if(n < 2)
      result = 1;
    else{
      result = n * factorial(n-1);
    }
    return result;
}

আপনি সম্ভবত এটি করতেন

int factorial(int n){
    if(n < 2)
      return 1;
    return n * factorial(n-1);
}

কেন? কারণ ঝনঝনানি সেই resultপরিবর্তনশীল সন্নিবেশ করবে যা আপনার জন্য রিটার্ন মান রাখে। হ্যাঁ. এটাই এর সঠিক উদ্দেশ্য %1। আপনার কোডের কিছুটা সংশোধিত সংস্করণের জন্য আইআর দেখুন।

সংশোধিত কোড,

enum days {MON, TUE, WED, THU};

int main() {
    enum days d;
    d = WED;
    if(d) return 1;
    return 0;
}

আইআর,

define dso_local i32 @main() #0 !dbg !15 {
    %1 = alloca i32, align 4
    %2 = alloca i32, align 4
    store i32 0, i32* %1, align 4
    store i32 2, i32* %2, align 4, !dbg !22
    %3 = load i32, i32* %2, align 4, !dbg !23
    %4 = icmp ne i32 %3, 0, !dbg !23
    br i1 %4, label %5, label %6, !dbg !25

 5:                                                ; preds = %0
   store i32 1, i32* %1, align 4, !dbg !26
   br label %7, !dbg !26

 6:                                                ; preds = %0
  store i32 0, i32* %1, align 4, !dbg !27
  br label %7, !dbg !27

 7:                                                ; preds = %6, %5
  %8 = load i32, i32* %1, align 4, !dbg !28
  ret i32 %8, !dbg !28
}

এখন আপনি দেখতে পাচ্ছেন যে %1নিজেকে উপকারী হুঁ? অন্যরা যেমন উল্লেখ করেছে, কেবলমাত্র একটি রিটার্ন স্টেটমেন্ট সহ ফাংশনগুলির জন্য, এই ভেরিয়েবলটি সম্ভবত এলএলভিএম এর সর্বোত্তম পাসগুলির মধ্যে একটি ছিনিয়ে নেবে।


1

কেন এই বিষয়টি - আসল সমস্যাটি কী?

আমি মনে করি আপনি যে গভীর উত্তরটির সন্ধান করছেন তা হতে পারে: এলএলভিএমের স্থাপত্যগুলি মোটামুটি সরল সীমারেখা এবং অনেকগুলি পাসের উপর ভিত্তি করে। সীমান্তগুলিকে সঠিক কোড উত্পন্ন করতে হবে, তবে এটি ভাল কোড হতে হবে না। তারা কার্যকর কাজটি করতে পারে।

এই ক্ষেত্রে, কলং কয়েকটি নির্দেশিকা উত্পন্ন করে যা কোনও কিছুর জন্য ব্যবহার না করে। এটি সাধারণত কোনও সমস্যা নয়, কারণ এলএলভিএমের কিছু অংশ অতিরিক্ত অতিরিক্ত নির্দেশাবলী থেকে মুক্তি পাবে। ঝাঁকুনি এটি ঘটতে বিশ্বাস করে। ঝাঁকুনির ডেড কোড নির্গমন এড়ানোর দরকার নেই; এর বাস্তবায়ন যথার্থতা, সরলতা, পরীক্ষাযোগ্যতা ইত্যাদির উপর দৃষ্টি নিবদ্ধ করতে পারে etc.


1

কারণ ঝাঁকুনি সিনট্যাক্স বিশ্লেষণের সাথে সম্পন্ন হয়েছে তবে এলএলভিএম এমনকি অপ্টিমাইজেশান দিয়ে শুরু হয়নি।

ক্ল্যাংয়ের সামনের প্রান্তটি আইআর (অন্তর্বর্তী উপস্থাপনা) তৈরি করেছে মেশিন কোডটি নয়। সেই পরিবর্তনগুলি হ'ল এসএসএ (একক স্ট্যাটিক অ্যাসাইনমেন্টস); তারা নিবন্ধগুলি এখনও আবদ্ধ হয় নি এবং আসলে অপ্টিমাইজেশনের পরে, কখনও হবে না কারণ তারা অনর্থক।

এই কোডটি উত্সটির কিছুটা আক্ষরিক উপস্থাপনা। এটিই অপ্টিমাইজেশনের জন্য এলএলভিএমের কাছে ঝাঁকুনি দেয়। মূলত, এলএলভিএম এটি দিয়ে শুরু হয় এবং সেখান থেকে অনুকূলিত হয়। প্রকৃতপক্ষে, সংস্করণ 10 এবং x86_64 এর জন্য, llc -O2 শেষ পর্যন্ত উত্পন্ন করবে:

main: # @main
  xor eax, eax
  ret

আমি এই স্তরের প্রক্রিয়া বুঝতে। আমি জানতে চেয়েছিলাম কেন এই আইআরটি শুরু করার জন্য উত্পন্ন হয়েছিল।
ম্যাকলজিন

আপনি একক পাস হিসাবে একটি সংকলক চিন্তা করতে পারেন। কলংয়ের সামনের প্রান্তটি দিয়ে পাসের পাইপলাইন রয়েছে যা আইআর উত্পন্ন করে। এমনকি এটি এই টেক্সচুয়াল আইআর তৈরি করতে পারেনি যার পরিবর্তে কেউ ক্ল্যাং -emit-llvm -S file.cpp এর মাধ্যমে অনুরোধ করেছিল Cla কলং আসলে আইআর এর একটি বাইনারি সিরিয়ালাইজেবল বিটকোড সংস্করণ তৈরি করেছিল। এলএলভিএম একাধিক পাস, প্রতিটি আইআর গ্রহণ এবং অপ্টিমাইজ হিসাবে কাঠামোগত। প্রথম এলএলভিএম পাস কলং থেকে আইআর নেয়। আইআর লাগে কারণ আপনি একই অপটিমাইজার + কোড জেনারেটরের সাথে অন্য কোনও ভাষা সমর্থন করার জন্য ফোর্টরান এফই দিয়ে কলং প্রতিস্থাপন করতে পারেন।
ওলসনিস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.