'constraints' performs resolution of operand constraints and assigns calculated constraints (Opnd::ConstraintKind_Calculated) to operands.
The resulting calculated constraints of operands determine allowable physical location for the operand.
This transformer allows to insert operands into instructions before it regardless instruction constraints except that Initial constraints of explicit instruction operands must have non-null intersections with corresponding constraints of at least one opcode group of the instruction.
ConstraintResolver analyzes instruction constraints and splits operands when necessary.
This transformer ensures that
1) All instruction constraints for EntryPoints, CALLs and RETs are set appropriately (IRManager::applyCallingConventions())
2) All operands has non-null calculated constraints
3) All operands fits into instructions they are used in (in terms of instruction constraints)
Original code piece:
I38: (AD:s65:double) =CopyPseudoInst (AU:t1:double) I32: MULSD .s65.:double,.t2:double I33: RET t66(0):int16 (AU:s65:double)
RET imposes constraint on s65 requiring to place it into FP0 register (its FP0D alias in this particular case)
MULSD imposes constraint on s65 requiring to place it into XMM register
After the pass:
I38: (AD:s65:double) =CopyPseudoInst (AU:t1:double) I32: MULSD .s65.:double,.t2:double I46: (AD:t75:double) =CopyPseudoInst (AU:s65:double) I33: RET t66(20):int16 (AU:t75:double)
Thus, ConstraintResolver inserted I46 splitting s65 to s65 and t75. s65 is assigned with Mem|XMM calculated constraint and t75 is assigned with FP0D calculated calculated constraint
4) If the live range of an operand crosses a call site and the operand is not redefined in the call site, the calculated constraint of the operand is narrowed the callee-save regs or memory (stack)
5) If the operand (referred as original operand here) is live at entry of a catch handler then necessary operand splitting is performed as close as possible to the instruction which caused the splitting and original operand is used before and after the instruction.
The main principle of the algorithm is anding of instruction constraints into operand calculated constraints and splitting operands to ensure that the calculated constraint is not null
This transformer must be inserted before register allocator which relies on calculated operand constraints.
header file: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Constraint.h
implementation file: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Constraint.cpp