Graal/Truffle do not have to obey the vast bulk of the Java type system.

Together they are fairly mind bending projects so it's important to understand precisely how they work. I've been studying them for about six months now so hopefully this explanation isn't too garbled.

The typical code flow in a JVM looks like this:

1. Bytecode loading and verification. This is where the type system is enforced.

2. Interpreting the byte code

3. C1 compiler (very fast, low quality output) compiles bytecode to native code, inserts into the code cache.

4. Very hot code gets recompiled using C2 (slower, high quality output).

Graal inserts itself into and replaces step 4. Once bytecode verification is done, the JVM itself imposes very little in the way of typing. You can actually disable verification with a command line flag, and then bad bytecode will segfault the JVM. The core VM sees code as being composed of methods which are contained in classes, and it wants pointers to be distinct from integers, but otherwise the JIT compilers can produce code that hardly match the Java worldview at all.

Graal is a Java JIT compiler that is, itself, written in Java. Thus it is a module which is passed some sort of input, which can be verified bytecode but can also be something else (e.g. textual source code, or LLVM bytecode), and the result of that is Graal inserting compiled code and generated metadata into the code cache. The core HotSpot engine then takes care of swapping it into the program when it's safe to do so.

So whilst Graal can compile Java bytecode (and do cutting edge optimisations whilst it does), it isn't required to do so, and thus execution of LLVM bytecode like in this example doesn't work by translation to Java bytecode, it just bypasses the bytecode layers of the VM entirely.

And that's where Truffle comes in. Because Graal is written in Java it's quite easy to expose a clean OO API, and it does so. So you can write programs that manipulate or generate Graal's IR (which is a graph based IR) and thus compile code to use the rest of the HotSpot runtime services. However graph IR is a very low level way of thinking about a program. So there is this higher level, Truffle, which allows you to write an AST interpreter in Java. It comes with what they call the Truffle domain specific language, which isn't a language at all but rather a set of annotations, and you can annotate your interpreter to indicate how it should be optimised. And then Graal takes the interpreter and the interpreter's input together, and does some incredibly aggressive optimisations on them, exploiting the fact that the compiler knows what the input to the program is. And like magic the interpreter gets loop unrolled and the overhead is boiled away until you have a JIT compiled program.

Thus for the low low price of an AST interpreter, you get a full blown optimising JITC, high end garbage collector, language interop framework etc all 'for free'. It's really quite radical and the trivial effort of writing AST interpreters means that they now have Graal/Truffle engines for Ruby, Python 3, R, Javascript, C in both raw/unsafe and managed varieties, and of course treating LLVM bytecode as a "language" is the next step.

So to answer your questions - no, type speculation is not required to work around the Java type system. It's just that profile guided speculative optimisations can often improve all kinds of programs and Graal is an aggressively speculating compiler, speculation is just fundamental to its design. And your last question doesn't really make sense because Graal integrates so tightly that it isn't so much using HotSpot, rather, it actually becomes HotSpot. And then of course it can write its PICs however it likes.