[llvm-commits] [PATCH] TableGen backend support to express relations between instruction
Sean Silva
silvas at purdue.edu
Thu Oct 18 17:05:14 PDT 2012
Thanks Jyotsna, the documentation looks great. A couple tiny nits
about the documentation and a comment at the end about the code:
+TableGen uses the above relationship model to emit relation table that maps
+non-predicated instructions with their predicated forms. It also outputs an
+interface function
+``short getPredOpcode(unsigned Opcode, bool PredSense)`` to query the
+table. Here, Function ``getPredOpcode`` takes two arguments, opcode of the
It looks like this description is out of date with the header comment
in utils/TableGen/CodeGenMapTable.cpp. You may want to move the
description of the signature to the beginning of the example, since
this signature is the "goal" of the instruction mapping; otherwise the
reader will be kind of lost until they reach the end.
+instruction and returns its predicated true or flase form depending on some
flase -> false
+void MapTableEmitter::emitBinSearch(raw_ostream &OS, unsigned TableSize) {
+ OS << " unsigned mid;\n";
+ OS << " unsigned start = 0;\n";
+ OS << " unsigned end = " << TableSize - 1 << ";\n";
+ OS << " while (start <= end) {\n";
+ OS << " mid = (end + start)/2;\n";
+ OS << " if (Opcode == " << InstrMapDesc.getName() << "Table[mid][0]) {\n";
+ OS << " break;\n";
+ OS << " }\n";
+ OS << " if (Opcode < " << InstrMapDesc.getName() << "Table[mid][0])\n";
+ OS << " end = mid - 1;\n";
+ OS << " else\n";
+ OS << " start = mid + 1;\n";
+ OS << " }\n";
+ OS << " if (start > end)\n";
+ OS << " return -1; // Instruction doesn't exist in this table.\n\n";
+}
This code is buggy. In `end = mid - 1` could evaluate to UINT_MAX in
the case of `TableSize == 2`, since `start` will be initialized to 0,
`end` will be initialized to `1`, so `mid` will be `(0+1)/2` which is
0. Then if the given opcode is less than the value in the table, you
will perform `end = mid - 1` which gives UINT_MAX.
I recommend using half-open ranges with a loop invariant "the element
we are looking for, if present, is in the range [start,end)", and the
termination condition is `start == end`. Also, `mid = (end + start)/2`
is potentially dangerous, since (end+start) could overflow an unsigned
and then dividing by 2 will give an undesired result; it is better to
do `mid = start + (end - start)/2`. Alternatively, if you know that
you can count on <algorithm> in this code, just use
std::lower_bound().
Also, I'm not sure if this routine is meant to return `-1` as an error
code (are clients going to be checking this?). If clients are not
expected to check this, then you should probably assert that an entry
was found in the table.
-- Sean Silva
On Thu, Oct 18, 2012 at 4:22 PM, Jyotsna Verma <jverma at codeaurora.org> wrote:
> Jakob,
>
> This patch addresses all your review comments. Please let me know if it's
> good to commit.
>
> Sean,
>
> I have moved documentation into its own file, HowToUseInstrMappings.rst and
> I have added a link to it from WritingLLVMBackend.html file. I have
> restructured the document to incorporate some of your suggestions. Please
> let me know if there are any other suggestions. However, I would prefer to
> address any major document related issues in a separate patch instead of
> holding the entire feature.
>
> Thanks,
> Jyotsna
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
> The Linux Foundation
>
>
>> -----Original Message-----
>> From: Jakob Stoklund Olesen [mailto:stoklund at 2pi.dk]
>> Sent: Friday, October 12, 2012 6:53 PM
>> To: Jyotsna Verma
>> Cc: 'Sean Silva'; llvm-commits at cs.uiuc.edu
>> Subject: Re: [llvm-commits] [PATCH] TableGen backend support to express
>> relations between instruction
>>
>>
>> On Oct 11, 2012, at 8:35 AM, Jyotsna Verma <jverma at codeaurora.org>
>> wrote:
>>
>> > Hello Jakob/Sean,
>> >
>> > Here is the updated patch which addresses your review comments.
>> > Please take a look and let me know if you have any other suggestions.
>>
>> Please use uint16_t for opcodes instead of 'short' everywhere.
>>
>> +typedef std::map<std::string, std::vector<Record*> > InstrRelMapTy;
>>
>> It's not clear why you're keying this map on instruction names instead of
>> using the much more efficient DenseMap<Record*,.>.
>>
>> +// Compare operator used by RowInstrMap to order keys that are vectors
>> +of Init // pointers.
>> +struct InstrMapComp {
>> + bool operator() (const std::vector<Init*>& lhs,
>> + const std::vector<Init*>& rhs) const {
>>
>> Why is this needed?
>>
>> +void MapTableEmitter::buildRowInstrMap(raw_ostream &OS) {
>>
>> What's the raw_ostream for?
>>
>> + RowInstrMapTy::iterator II, IE;
>> + II = RowInstrMap.find(KeyValue);
>> + IE = RowInstrMap.end();
>> + if (II == IE) {
>> + InstrList.push_back(CurInstr);
>> + std::pair<std::vector<Init*>, std::vector<Record*> >
>> + KeyValuePair(KeyValue,
> InstrList);
>> + RowInstrMap.insert(KeyValuePair);
>> + }
>> + else {
>> + II->second.push_back(CurInstr);
>> + }
>>
>> RowInstrMap[KeyValue].push_back(CurInstr);
>>
>> +//===------------------------------------------------------------------
>> +----===//
>> +// Output two-level relation tables.
>> +
>>
>> I'm rather skeptical about the compile time improvements you can get with
>> this compared to a simple binary search.
>>
>> Please save this for a later patch, and include some compile time
>> measurements so we know it is worth the extra complexity.
>>
>> + OS << "short "<<InstrMapDesc.getName() << "Table[]["<< NumCol+1 << "]
>> + = {\n";
>>
>> Tables are constant.
>>
>> Please emit just a single function per mapping. The tables can be local to
> the
>> function, and the binary search algorithm should be duplicated so it
> doesn't
>> need to deal with dynamic row sizes.
>>
>> /jakob
>
More information about the llvm-commits
mailing list