From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 118918 invoked by alias); 24 Jun 2015 00:48:30 -0000 Mailing-List: contact jit-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: Sender: jit-owner@gcc.gnu.org Received: (qmail 118902 invoked by uid 89); 24 Jun 2015 00:48:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.98.7 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: mx1.redhat.com Message-ID: <1435106449.13727.35.camel@surprise> Subject: Re: switches in GCC JIT? From: David Malcolm To: Dibyendu Majumdar Cc: Basile Starynkevitch , jit@gcc.gnu.org Date: Thu, 01 Jan 2015 00:00:00 -0000 In-Reply-To: References: <558880D7.7080503@starynkevitch.net> <1435009326.13727.16.camel@surprise> <558885E4.20706@starynkevitch.net> <1435019126.13727.21.camel@surprise> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-SW-Source: 2015-q2/txt/msg00102.txt.bz2 On Tue, 2015-06-23 at 21:01 +0100, Dibyendu Majumdar wrote: > On 23 June 2015 at 01:25, David Malcolm wrote: > > As it happens, none of the bytecode languages I've implemented so far > > have switch-like constructs. > > > > Often bytecodes in dynamic languages when translated do not exactly > map to C constructs, so this is not surprising I think. > > > But I see now that the JVM has opcodes "lookupswitch" and "tableswitch"; > > those alone make a compelling case for libgccjit supporting switches. > > > > I'm working on it now; the API I'm thinking of looks like this: > > > > extern void > > gcc_jit_block_end_with_switch (gcc_jit_block *block, > > gcc_jit_location *loc, > > gcc_jit_rvalue *expr, > > gcc_jit_block *default_block, > > int num_cases, > > gcc_jit_rvalue **case_min_values, > > gcc_jit_rvalue **case_max_values, > > gcc_jit_block **case_blocks); > > > > > > thus supporting ranged cases, whilst also allowing individual values, by > > simply passing in the same table for both case_min_values and > > case_max_values. > > (fwiw I have it mostly working) > The API looks ok to me but would it be more user friendly if you > created a struct to hold the case values and blocks together? That is: > > struct case { > gcc_jit_rvalue *min_value; > gcc_jit_rvalue *max_value; > gcc_jit_block *block; > }; > > Then the last three parameters could be replaced by 'struct case *'. Is is actually easier that way? If so, it would probably need to be "struct gcc_jit_case", both for the sake of namespacing, and because "case" is a reserved word. That said, it would be the first non-opaque struct in the API, which makes me nervous; I guess we could make it opaque like this: extern gcc_jit_case * gcc_jit_context_new_case (gcc_jit_context *ctxt, gcc_jit_rvalue *min_value, gcc_jit_rvalue *max_value, gcc_jit_block *block); though I don't know if that's better. I prefer the original API, fwiw (with 3 arrays), as it doesn't introduce a new type. > >> BTW, if we don't have switches, we should at least have indirect jumps, > >> and the ability to retrieve, as a label, the starting address of any > >> basic block. (i.e. the equivalent of goto *ptr; and of &&label in C). If > >> that is possible today, we need more documentation about that (at least > >> saying that switch statements could be translated that way) > >> > > It would also be useful to have the indirect jump capability - LLVM > offers this and I used it in Ravi to help with performance (although > in the particular use case I did not really see much benefit). This isn't yet supported by libgccjit. Maybe the API might look something like this: extern gcc_jit_rvalue * gcc_jit_block_get_address (gcc_jit_block *block); giving an rvalue of type void *, and: extern void gcc_jit_block_end_with_indirect_jump (gcc_jit_block *block, gcc_jit_rvalue *expr); where "expr" must be of type void *, obtained via gcc_jit_block_get_address. That said, what use-cases are you thinking of? The one I'm familiar with is threaded dispatch of the big switch statement typically seen in an interpreter, but presumably anyone using libgccjit is unrolling the switch statement into code. Dave