2012-03-14 41 views
5

I tienen el archivo IR followint LLVM¿Borrando una primera instrucción en bloque básico de LLVM IR?

%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 

En ella estoy primera carga vairable "i" en% 1 y variable "j" en% 2 entonces yo estoy comparando el mayor de condición que es (i> j). Basado en eso, hay una rama en la etiqueta 4 o en la etiqueta 6. Mi problema es que hay dos instrucciones de carga para la variable "i" una en el primer bloque básico y otra en el 2º bloque básico. Aquí quiero eliminar la segunda instrucción de carga. Para ello, lo hago como cuando llego a la instrucción de carga 2 para la variable "i". Estoy reemplazando todos los usos de la 2da instrucción por la primera instrucción, luego borro la instrucción actual, es decir, 2da. Aquí no puedo establecer el puntero del iterador de instrucción. No quiero configurar para la próxima instrucción (almacenar i32% 5, i32 *% k, alinear 4). ¿Hay alguna otra forma? Si sabes, házmelo saber.

+0

No estoy seguro de que comprenda su pregunta. Pero estoy bastante seguro de que los pases posteriores deberían poder eliminar esa carga fácilmente para ti, así que realmente no me molestaría. Si tiene una razón convincente para eliminar la carga, vuelva a formular su pregunta, ya que no puedo entender cuál es realmente su problema. – CAFxX

+0

Mi problema es que después de eliminar la segunda instrucción de carga, quiero configurar el iterador de instrucciones de manera que en la siguiente iteración alcance (almacenar i32% 5, i32 *% k, alinear 4) porque en el bucle estoy incrementando el iterador de instrucción . – damrudhard

+0

¿Por qué no simplemente obtener un nuevo iterador llamando 'BB-> begin()' de nuevo inmediatamente después de 'inst-> eraseFromParent()'? – CAFxX

Respuesta

10

Si le entiendo correctamente, todo lo que quiere es simplemente borrar una instrucción y seguir iterando sobre el código. Si eso es correcto, echar un vistazo a este ejemplo de la DeadInstElimintation pase (que vive en lib/Transforms/Scalar/DCE.cpp):

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; 
} 

Lo interesante observar es cómo se incrementa el iterador. El DI++ no se hace dentro de la última cláusula del for, sino más bien por separado, con el DI actual asignado al Inst. Esto asegura que incluso si elimina Inst, DI ya apunta a la siguiente instrucción, de modo que el ciclo seguirá corriendo sobre las siguientes instrucciones.

+0

Recibí una solución de CAFxX. Gracias a ti también por tu ayuda. – damrudhard

+0

@damrudhard: establecer el nuevo iterador en 'BB-> begin()' solo funcionará si la nueva instrucción es la primera en el bloque básico. De lo contrario, volverás algunas instrucciones. Si esto está bien con usted, entonces no hay problema. Creo que la solución que se muestra en mi respuesta es más general, sin embargo. –

+0

En otro caso, estoy configurando el iterador de instrucciones a las instrucciones anteriores para que en la siguiente iteración apunte a la instrucción inmediatamente después de la eliminada. – damrudhard

Cuestiones relacionadas