Question on arithmetic overflow detection support in C2

Vladimir Kozlov vladimir.kozlov at oracle.com
Wed Jun 20 19:03:42 PDT 2012


As you see "o45 Proj === o43" does not produce RFLAG so matcher can't match it.
ProjNode::ideal_reg() for overflow_proj_num should return Op_RegFlags.

Vladimir

Krystal Mok wrote:
> On Thu, Jun 21, 2012 at 8:03 AM, Vladimir Kozlov 
> <vladimir.kozlov at oracle.com <mailto:vladimir.kozlov at oracle.com>> wrote:
> 
>     Krystal Mok wrote:
> 
>         Thanks for the reply! Comments inline below:
> 
>         On 2012-6-21, at 6:13, Vladimir Kozlov
>         <vladimir.kozlov at oracle.com <mailto:vladimir.kozlov at oracle.com>>
>         wrote:
> 
>             Look on output before assert message. It should have
>             problematic ideal subgraph dump which it can't match.
> 
>         The output is:
> 
> 
>     You did not send output.
> 
> Oops, I hit the send button too early ...
> 
> Here's the output:
> 
> o30 If === o5 o46 o45  [[o31 o32  6 ]] P=0.000001, C=-1.000000
> 
> --N: o30 If === o5 o46 o45  [[o31 o32  6 ]] P=0.000001, C=-1.000000
> 
>    --N: o46 Bool === _ o45  [[o30 ]] [??]
>    CMPOP  0  CMPOP
>    CMPOPU  0  CMPOPU
> 
>    --N: o45 Proj === o43  [[o46 o30 ]] #1
>    RREGI  0  RREGI
>    RAX_REGI  0  RAX_REGI
>    RBX_REGI  0  RBX_REGI
>    RCX_REGI  0  RCX_REGI
>    RDX_REGI  0  RDX_REGI
>    RDI_REGI  0  RDI_REGI
>    NO_RCX_REGI  0  NO_RCX_REGI
>    NO_RAX_RDX_REGI  0  NO_RAX_RDX_REGI
>    STACKSLOTI  100  storeSSI
> 
>  
> 
> 
> 
>             I think the problem is that you have Proj node in between If
>             and CheckedAddI nodes so that it can't match 'If' node since
>             it looks for inputs which produce flags (cr). May be
>             CheckedAddINode::match() is not enough.
> 
>         You're right, that's exactly what's happening.
> 
> 
> One more question on this one: how does the matcher know that the data 
> projection should be in the same location as the dst input? There's 
> nowhere to specify it.
>  
> 
> 
>             Also you can't use EMPTY mask for data result projection.
>             Bind it to an register as DivMod node.
> 
> 
>     Mask should reflect in what registers could be result. You don't
>     need to bind to specific register but you need to return non-empty
>     mask, for example, INT_REG_mask(). And for flag projection you need
>     INT_FLAGS_mask().
> 
> 
> Ahh, so the register class declaration for RFLAGS moved to x86.ad 
> <http://x86.ad> ... no wonder I couldn't find it when I searched 
> x86_64.ad <http://x86_64.ad>.
> 
> I'm still getting the same crash after I changed 
> CheckedAddINode::match() to this:
> 
> Node* CheckedAddINode::match(const ProjNode* proj, const Matcher* match) {
>   uint ideal_reg = proj->ideal_reg();
>   RegMask rm = RegMask::Empty;
>   if (proj->_con == sum_proj_num) {
>     rm = match->checkedAddI_sum_proj_mask();
>   } else {
>     assert(proj->_con == overflow_proj_num, "must be sum or overflow 
> projection");
>     ideal_reg = Op_RegFlags;
>     rm = match->overflow_proj_mask();
>   }
>   return new (match->C, 1) MachProjNode(this, proj->_con, rm, ideal_reg);
> }
> 
> Where both RegMasks specified as suggested above. The output log is 
> still the same.
> 
> Thanks,
> Kris
>  
> 
> 
> 
>     Vladimir
> 
> 
>         But in the DivMod case, both data projections had to be in fixed
>         registers because that's required by idiv, where as here binding
>         the sum projection to a fixed register (e.g. rax) would be less
>         optimal, right?
> 
>         If only there's a way to express the (Set dest ...) semantic for
>         CheckedAddI's data projection ...
> 
>         Anyway, binding it fixed should at least get the example
>         running. I'll try this first and look for alternative solutions
>         later.
> 
>             And use masm instructions encoding
> 
>              ins_encode %{
>               __ addl($dst$$Register, $src$$Register);
>              %}
> 
>             instead of
> 
>              ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
> 
>         Will fix this one. I just copied the code from the basic
>         instruct for AddI, which is still using the old ins_encode form.
> 
>         Thanks,
>         Kris
> 
>             Vladimir
> 
>             Krystal Mok wrote:
> 
>                 Thank you for all your input, John and Vladimir!
>                 I'm close to getting some prototype that could actually
>                 run...but not there just yet.
>                 I've got Match.addExact(int, int) compiled down to this
>                 graph:
>                 http://dl.iteye.com/upload/__picture/pic/114582/cc7535db-__20d8-3e5d-9abd-b96456c7166c.__png
>                 <http://dl.iteye.com/upload/picture/pic/114582/cc7535db-20d8-3e5d-9abd-b96456c7166c.png>
>                 with the CheckedAddI node resembling the way DivModI works.
>                 But apparently I'm not getting the Matcher part right
>                 yet. I'm getting this error message:
>                 #  Internal Error
>                 (/home/sajia/temp/hotspot-__comp/src/share/vm/opto/__matcher.cpp:1564),
>                 pid=16856, tid=1117243712
>                 #  assert(false) failed: bad AD file
>                 from this stack trace:
>                 V  [libjvm.so+0xb10bea]
>                  VMError::report(outputStream*)__+0xfa4
>                 V  [libjvm.so+0xb11f77]  VMError::report_and_die()+__0x649
>                 V  [libjvm.so+0x59e706]  report_vm_error(char const*,
>                 int, char const*, char const*)+0x9c
>                 V  [libjvm.so+0x8d4af0]  Matcher::Label_Root(Node
>                 const*, State*, Node*, Node const*)+0x48c
>                 V  [libjvm.so+0x8d4d0f]  Matcher::match_tree(Node
>                 const*)+0x205
>                 V  [libjvm.so+0x8d6397]  Matcher::xform(Node*, int)+0x16d
>                 V  [libjvm.so+0x8d9ea2]  Matcher::match()+0xb0e
>                 V  [libjvm.so+0x52e20f]  Compile::Code_Gen()+0x91
>                 V  [libjvm.so+0x537678]  Compile::Compile(ciEnv*,
>                 C2Compiler*, ciMethod*, int, bool, bool)+0x101e
>                 V  [libjvm.so+0x47aa8c]
>                  C2Compiler::compile_method(__ciEnv*, ciMethod*, int)+0xea
>                 V  [libjvm.so+0x53e552]
>                  CompileBroker::invoke___compiler_on_method(__CompileTask*)+0x332
>                 V  [libjvm.so+0x540f10]
>                  CompileBroker::compiler___thread_loop()+0x2fa
>                 V  [libjvm.so+0xabed88]
>                  compiler_thread_entry(__JavaThread*, Thread*)+0x54
>                 V  [libjvm.so+0xac288c]
>                  JavaThread::thread_main_inner(__)+0x102
>                 V  [libjvm.so+0xac4f0b]  JavaThread::run()+0xef
>                 V  [libjvm.so+0x979557]  java_start(Thread*)+0x16f
>                 The current status of the patch is avaiable here:
>                 https://gist.github.com/__05f6f33cb01c7f5aedf3
>                 <https://gist.github.com/05f6f33cb01c7f5aedf3>
>                 I haven't done a full-fledged intrinsic for
>                 Math.addExact(int, int) yet; just as a prototype, I'm
>                 faking the use of CmpAddI node right now. At the end of
>                 Optimize(), I pattern match for the overflow checking
>                 logic, replace it with a new fake CmpAddI node, then
>                 make the actual CheckedAddI node from the CmpAddI,
>                 finally replace the old AddI and Bool nodes.
>                 Most of the changes besides the new nodes are for adding
>                 the overflow/no-overflow conditions to BoolTest and cmpOp.
>                 If there were separate AddI and CmpAddI nodes, they
>                 would have had a (Set dst ...) and (Set cr ...) in their
>                 match rule. But I can't see how I can express it here.
>                 Regards,
>                 Kris
> 
> 


More information about the hotspot-compiler-dev mailing list