210 likes | 333 Views
Ordering and Liveness Analysis. ลำดับและการวิเคราะห์บอกความเป็นอยู่หรือความตาย. Ordering. Top bottom และ ค่าคงที่ c คือ abstract value ค่าที่เราใช้แทนเซ็ทของ concrete value ที่เป็นไปได้ ณ เวลาที่โปรแกรมทำงาน
E N D
Orderingand Liveness Analysis ลำดับและการวิเคราะห์บอกความเป็นอยู่หรือความตาย
Ordering • Top bottom และ ค่าคงที่ c คือ abstract value • ค่าที่เราใช้แทนเซ็ทของ concrete value ที่เป็นไปได้ ณ เวลาที่โปรแกรมทำงาน • ในกรอบการวิเคราะห์ dataflow เราจะมีการกำหนดลำดับขั้น (ordering) ของ value • เช่นในกรณีของ constant propagation เราให้ว่า ⊥ < c < T • ภาพของ ordering ใน constant propagation สามารถเขียนได้ตามรูปด้านล่าง โดยค่าที่ต่ำที่สุดจะอยู่ในตำแหน่งล่างที่สุด • ค่าคงที่ c ที่เป็นไปได้ทุกๆค่าอยู่ในลำดับเดียวกัน T ⊥
Ordering • T คือค่าที่มากที่สุด⊥คือค่าที่น้อยที่สุด • ค่าคงที่ที่เป็นไปได้ที่อยู่ระหว่างสองค่านี้มีศักย์เสมอกัน • เรียกว่า incomparable • ให้ lubคือค่า least-upper bound ของ ordering นี้ • กฏ 1-4 ของ constant propagation สามารถเขียนในรูป lubได้ดังนี้: • C(s, x, in) = lub { C(p, x, out) | p is a predecessor of s }
Termination • การที่เรามี lubและ ordering จะช่วยเราในการให้เหตุผลการมีจุดจบ (termination) ของอัลกอริทึมที่ใช้ • อัลกอริทึมของ CP เราบอกอย่างหลวมๆว่าให้ทำซ้ำกฏทั้งหมดจน “ไม่มีอะไรเปลี่ยนแปลง” • นั่นไม่ได้ยืนยันว่าในที่สุดจะ “ไม่มีอะไรเปลี่ยนแปลง” • ค่าในการวิเคราะห์ CP จะเริ่มจาก⊥และเพิ่มขึ้นเรื่อยๆ • ⊥เปลี่ยนเป็นค่าคงที่และค่าคงที่เปลี่ยนเป็น T • เพราะฉะนั้น C(s, x, in) และ C(s, x, out) จะเปลี่ยนได้อย่างมากสองครั้ง
Termination • ดังนั้นอัลกอริทึมจะมี runtime เป็น O(n) โดยที่ n คือขนาดของโปรแกรม (จำนวนคำสั่ง) • จำนวนขั้นตอนการคำนวณ • = จำนวน C(…)* 2 • = จำนวนคำสั่ง * 4
Liveness Analysis • หลังจากทำ constant propagation เราสามารถกำจัดคำสั่ง X := 3 ได้หรือไม่ • กำจัดได้ถ้า X := 3 เป็นค่าที dead นั่นคือ X ไม่มีการใช้งาน (อ่าน) หลังจากนี้
Live กับ Dead • ค่า X ค่าแรก dead เพราะไม่เคยมีการใช้ • ค่า X ที่สอง live เพราะอาจจะมีการใช้ ณ ที่แห่งใดในโปรแกรม • คุณสมบัติของ X ในลักษณะที่บอกว่าตำแหน่งใด live หรือdead เรียกว่า liveness
Liveness • ตัวแปร x จะ live ที่คำสั่ง s ถ้า • ถ้ามีคำสั่ง s’ ที่ใช้ x • มี path จาก s ไปที่ s’ • Path นี้ไม่มีคำสั่งที่ reassign ค่า x • คำสั่ง x := … จะเป็น dead code ถ้า x นั้น dead หลังจากคำสั่งนี้ • Dead code สามารถจะลบออกไปได้จากโปรแกรม • แต่การจะบอกได้ว่าตัวแปรใด live หรือ dead เราจะต้องทำการวิเคราะห์หาข้อมูล liveness
การคำนวณ Liveness • เราจะคำนวณ livenessโดยใช้หลักการเช่นเดียวกับ constant propagation • เราจะดูในระดับคำสั่งและพิจารณาข้อมูลที่ส่งผ่านจาก in ของคำสั่งไปที่ out ของคำสั่งนั้น • ในการคำนวณ livenessเราจะพิจารณาคุณสมบัติ live หรือ dead ของตัวแปร • มีความเป็นไปได้เพียงสองค่า • แทนคุณสมบัตินี้ด้วยค่า boolean (true หรือ false) • “ง่าย” กว่า constant propagation
อัลกอริทึมในการคำนวณ Liveness • ให้ค่า liveness L(…) ทุกๆตำแหน่งเป็น false ในตอนเริ่มต้น • ทำซ้ำจนกว่าทุกๆคำสั่ง s ในโปรแกรมจะเป็นไปตามกฏ 1-4 ของliveness ถ้ายังมีคำสั่งใดๆไม่เป็นไปตามนี้ เลือกคำสั่งนั้นและคำนวณ livenessโดยใช้กฏที่ได้กล่าวมา
ตัวอย่างการคำนวณ Livenessของตัวแปร x false x = 0; false true false true A: x = x + 1; if (x != 10) goto A false true false true false true false ให้ x dead หลังจากจุดนี้
Termination • ค่า livenessเปลี่ยนแปลงได้เฉพาะจาก false ไป true ได้ในทิศทางเดียว • ในทุกๆตำแหน่งค่าสามารถเปลี่ยนได้เพียงหนึ่งครั้งเท่านั้น • ดังนั้นสามารถการันตี termination ได้ • เมื่อเราวิเคราะห์หา livenessของตัวแปรได้แล้ว การกำจัด dead code สามารถทำได้อย่างง่ายและตรงไปตรงมา
การวิเคราะห์แบบ Forward และ Backward • เราได้เห็นการวิเคราะห์ในสองรูปแบบ: • Constant propagation เป็นการวิเคราะห์แบบ forward ค่าที่เกี่ยวข้องกับ CP จะถูกผลักจาก in ของคำสั่งไปสู่ out ของคำสั่ง • Livenessเป็นการวิเคราะห์แบบ backward ค่าที่เกี่ยวข้องกับ livenessจะถูกผลักจาก out ของคำสั่งกลับไปที่ in • ยังมีการวิเคราะห์เกี่ยวกับ global optimization แบบอื่นๆอีก • ส่วนใหญ่จะอยู่ในกลุ่มใดกลุ่มหนึ่ง forward หรือ backward • แต่ไม่ว่าจะเป็นกลุ่มใด หลักการวิเคราะห์ก็ยังยึดหลัก dataflow ที่ ใช้กฏในระดับคำสั่งบอกความสัมพันธ์ของข้อมูลที่ in และ out ของคำสั่งนั้น
ปัญหา Register Allocation • IR ใช้ตัวแปร temporary ไม่จำกัดจำนวน • ช่วยในเรื่อง optimization • แต่จะยากต่อการผลิต assembly code • ตัวแปร temporary มีจำนวนมากกว่ารีจิสเตอร์ที่ CPU มีให้ • สิ่งที่ต้องทำ: • เปลี่ยนให้ IR ไม่มีการใช้ตัวแปร temporary ไปมากกว่ารีจิสเตอร์ที่ CPU มีให้ • จะต้องจัด temporary หลายๆตัวให้เข้าสู่รีจิสเตอร์หนึ่งตัว • การจัดการนี้ต้องไปกระทบพฤติกรรมของโปรแกรม
ตัวอย่าง • พิจารณาส่วนของโปรแกรมต่อไปนี้ • ให้ว่า a และ e dead หลังจากใช้งานแล้ว • ตัวแปร temporary a และ e สามารถนำกลับมาใช้งานได้อีกครั้งหนึ่ง • สามารถจัดให้ค่าของa e และ f ใส่ไว้ที่ register เพียงหนึ่งตัวได้ (r1) • ตัวแปร temporary ที่ dead สามารถกำจัดทิ้งไปและนำมาใช้ใหม่ได้
แนวคิดหลัก ตัวแปร t1 และ t2 สามารถใช้รีจิสเตอร์เดียวกันได้ถ้า ณ จุดใดๆของโปรแกรม มีตัวแปรตัวใดตัวหนึ่งเท่านั้นที่ live (นั่นคือ live สองตัวพร้อมกันไม่ได้) พูดอีกแบบหนึ่งก็คือ ถ้า t1 และ t2 live ณ จุดเดียวกันของโปรแกรม ทั้งสองจะไม่สามารถใช้รีจิสเตอร์เดียวกันได้