2012-03-14 12 views
5

I önce "i" '% 2,% 1 ve değişken "j" I den büyük olduğu durum (karşılaştırma am vairable yükleme am İçinde followint LLVM İR dosyasıLLVM IR'den Temel Bloktaki ilk Talimatı silme?

%1 = load i32* %i, align 4 
    %2 = load i32* %j, align 4 
    %3 = icmp sgt i32 %1, %2 
    br i1 %3, label %4, label %6 

; <label>:4          ; preds = %0 
    %5 = load i32* %i, align 4 
    store i32 %5, i32* %k, align 4 
    br label %6 

; <label>:6          ; preds = %5, %0 
    ret i32 0 

sahip i> j). Buna dayanarak, etiket 4'e veya etiket 6'ya dal vardır. Benim problemim, "i" değişkeni için birinci temel blokta ve diğeri de 2. temel blokta iki yük talimatı olmasıdır. Burada 2. yük talimatını kaldırmak istiyorum. Bunun için, "i" değişkeni için 2. yük talimatına ulaştığım gibi yapıyorum. İkinci talimatın tüm kullanımlarını ilk komutla değiştiriyorum, o zaman mevcut talimatı siliyorum, yani 2.. Burada komut iterator işaretçisi ayarlayamıyorum. Bir sonraki talimat için ayarlamak istemiyorum (i32% 5, i32 *% k, align 4). Başka bir yolu var mı? Biliyorsanız lütfen bana bildirin.

+0

Sorunuzu anladığımdan emin değilim. Ama eminim ki sonraki geçişler bu yükü sizin için kolayca kaldırabilmelidir, bu yüzden gerçekten rahatsız olmazdım. Yükü silmek için zorlayıcı bir nedeniniz varsa, lütfen sorunun ne olduğunu anlayamadığım için lütfen sorunuzu yeniden belirtin. – CAFxX

+0

Sorunum, ikinci yükleme komutunu sildikten sonra, komut yineleyicisini artırdığım için, iteratörün bir sonraki yinelemede (i32% 5, i32 *% k, 4 hizala) ulaşması gerektiği şekilde ayarlanmasını istiyorum. . – damrudhard

+0

Niçin 'inst-> deleteFromParent()' den hemen sonra 'BB-> begin()' diyerek yeni bir yineleyici almıyoruz? – CAFxX

cevap

10

Sizi doğru anlarsam, tek yapmanız gereken bir yönergeyi silmek ve kod üzerinde yinelemektir. bu doğru ise (lib/Transforms/Scalar/DCE.cpp yaşıyor) DeadInstElimintation geçişte şu örneğe bir göz atın:

virtual bool runOnBasicBlock(BasicBlock &BB) { 
    bool Changed = false; 
    for (BasicBlock::iterator DI = BB.begin(); DI != BB.end();) { 
    Instruction *Inst = DI++; 
    if (isInstructionTriviallyDead(Inst)) { 
     Inst->eraseFromParent(); 
     Changed = true; 
     ++DIEEliminated; 
    } 
    } 
    return Changed; 
} 

ilginçtir şey yineleyici artırılır nasıl. DI++, for'un son cümlesi içinde değil, ayrı olarak,Inst'a atanan geçerli olarak yapılmaz. Bu, Inst, DI'u silseniz bile, bir sonraki talimatı işaret etse bile, döngü sonraki talimatlar üzerinde çalışmaya devam etmesini sağlar.

+0

CAFxX'ten bir çözüm buldum. Yardımlarınız için teşekkürler. – damrudhard

+0

@damrudhard: Yeni yineleyiciyi 'BB-> begin()' olarak ayarlamak yalnızca yeni komut temel blokta ilk olduğunda işe yarayacaktır. Aksi takdirde birkaç talimatı geri alırsınız. Bu senin için sorun değilse, o zaman sorun yok. Yine de cevabımda gösterilen çözümün daha genel olduğunu düşünüyorum. –

+0

Diğer durumda, talimat yinelemesini bir önceki talimata ayarlıyorum, böylece bir sonraki iterasyonda, silinmiş olandan hemen sonra talimatını gösterecektir. – damrudhard