mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
Initial revision
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
120
docs/HistoricalNotes/2001-02-09-AdveComments.txt
Normal file
120
docs/HistoricalNotes/2001-02-09-AdveComments.txt
Normal file
@@ -0,0 +1,120 @@
|
||||
Ok, here are my comments and suggestions about the LLVM instruction set.
|
||||
We should discuss some now, but can discuss many of them later, when we
|
||||
revisit synchronization, type inference, and other issues.
|
||||
(We have discussed some of the comments already.)
|
||||
|
||||
|
||||
o We should consider eliminating the type annotation in cases where it is
|
||||
essentially obvious from the instruction type, e.g., in br, it is obvious
|
||||
that the first arg. should be a bool and the other args should be labels:
|
||||
|
||||
br bool <cond>, label <iftrue>, label <iffalse>
|
||||
|
||||
I think your point was that making all types explicit improves clarity
|
||||
and readability. I agree to some extent, but it also comes at the cost
|
||||
of verbosity. And when the types are obvious from people's experience
|
||||
(e.g., in the br instruction), it doesn't seem to help as much.
|
||||
|
||||
|
||||
o On reflection, I really like your idea of having the two different switch
|
||||
types (even though they encode implementation techniques rather than
|
||||
semantics). It should simplify building the CFG and my guess is it could
|
||||
enable some significant optimizations, though we should think about which.
|
||||
|
||||
|
||||
o In the lookup-indirect form of the switch, is there a reason not to make
|
||||
the val-type uint? Most HLL switch statements (including Java and C++)
|
||||
require that anyway. And it would also make the val-type uniform
|
||||
in the two forms of the switch.
|
||||
|
||||
I did see the switch-on-bool examples and, while cute, we can just use
|
||||
the branch instructions in that particular case.
|
||||
|
||||
|
||||
o I agree with your comment that we don't need 'neg'.
|
||||
|
||||
|
||||
o There's a trade-off with the cast instruction:
|
||||
+ it avoids having to define all the upcasts and downcasts that are
|
||||
valid for the operands of each instruction (you probably have thought
|
||||
of other benefits also)
|
||||
- it could make the bytecode significantly larger because there could
|
||||
be a lot of cast operations
|
||||
|
||||
|
||||
o Making the second arg. to 'shl' a ubyte seems good enough to me.
|
||||
255 positions seems adequate for several generations of machines
|
||||
and is more compact than uint.
|
||||
|
||||
|
||||
o I still have some major concerns about including malloc and free in the
|
||||
language (either as builtin functions or instructions). LLVM must be
|
||||
able to represent code from many different languages. Languages such as
|
||||
C, C++ Java and Fortran 90 would not be able to use our malloc anyway
|
||||
because each of them will want to provide a library implementation of it.
|
||||
|
||||
This gets even worse when code from different languages is linked
|
||||
into a single executable (which is fairly common in large apps).
|
||||
Having a single malloc would just not suffice, and instead would simply
|
||||
complicate the picture further because it adds an extra variant in
|
||||
addition to the one each language provides.
|
||||
|
||||
Instead, providing a default library version of malloc and free
|
||||
(and perhaps a malloc_gc with garbage collection instead of free)
|
||||
would make a good implementation available to anyone who wants it.
|
||||
|
||||
I don't recall all your arguments in favor so let's discuss this again,
|
||||
and soon.
|
||||
|
||||
|
||||
o 'alloca' on the other hand sounds like a good idea, and the
|
||||
implementation seems fairly language-independent so it doesn't have the
|
||||
problems with malloc listed above.
|
||||
|
||||
|
||||
o About indirect call:
|
||||
Your option #2 sounded good to me. I'm not sure I understand your
|
||||
concern about an explicit 'icall' instruction?
|
||||
|
||||
|
||||
o A pair of important synchronization instr'ns to think about:
|
||||
load-linked
|
||||
store-conditional
|
||||
|
||||
|
||||
o Other classes of instructions that are valuable for pipeline performance:
|
||||
conditional-move
|
||||
predicated instructions
|
||||
|
||||
|
||||
o I believe tail calls are relatively easy to identify; do you know why
|
||||
.NET has a tailcall instruction?
|
||||
|
||||
|
||||
o I agree that we need a static data space. Otherwise, emulating global
|
||||
data gets unnecessarily complex.
|
||||
|
||||
|
||||
o About explicit parallelism:
|
||||
|
||||
We once talked about adding a symbolic thread-id field to each
|
||||
instruction. (It could be optional so single-threaded codes are
|
||||
not penalized.) This could map well to multi-threaded architectures
|
||||
while providing easy ILP for single-threaded onces. But it is probably
|
||||
too radical an idea to include in a base version of LLVM. Instead, it
|
||||
could a great topic for a separate study.
|
||||
|
||||
What is the semantics of the IA64 stop bit?
|
||||
|
||||
|
||||
|
||||
|
||||
o And finally, another thought about the syntax for arrays :-)
|
||||
|
||||
Although this syntax:
|
||||
array <dimension-list> of <type>
|
||||
is verbose, it will be used only in the human-readable assembly code so
|
||||
size should not matter. I think we should consider it because I find it
|
||||
to be the clearest syntax. It could even make arrays of function
|
||||
pointers somewhat readable.
|
||||
|
Reference in New Issue
Block a user