This patch is in response to r223147 where the avaiable features are
computed based on ".cpu" directive. This will work clean for the standard
variants like cortex-a9. For custom variants which rely on standard cpu names
for aassembly, the additional features of a CPU should be propagated. This can be
done via ".arch_extension" as long as the assembler supports it.
Details
- Reviewers
rengolin t.p.northover apazos
Diff Detail
Event Timeline
This looks like only half a patch (it adds a new virtual method, but nothing calls it and there are no tests). Did you accidentally send the wrong file?
Yes Tim. This patch just adds the infrastructure to add the ".arch_extension".
My next patch is to emit ".cpu" and ".arch_extension" on krait CPU and add unit tests.
I think it'd be best to merge the two then. At the moment it's just dead code if we commit this patch as it is.
Cheers.
Tim.
Hi Sumanth,
Please, add the real use to this patch, as Tim said. You'll also want to change the binary output (object files), so that it doesn't matter which output you chose, the results will be the same. That also involves changing the build attributes.
cheers,
--renato
Sure guys. I will add the use case and update an unit test.
Renote, I am not sure on what you meant by this ?
You'll also want to change the binary output (object files), so that it doesn't matter which output you chose, the results will be the same. That also involves changing the build attributes.
So, in the integrated assembler, we deal with .fpu, .arch etc and change the feature bits, so that the IAS can cope with changing the default attributes. So, if you add tests, you'll have to make sure both assembly output has the new flag, but as well that the IAS works by understanding it from either internally, by emitting the correct instruction your Krait CPU can, but not A9, as well as being able to read an assembly file with A9 as CPU + arch_extension, or even "krait" as CPU, and not fail with "invalid instruction".
Does that make sense?
I am drafting an unit test on the lines of
llc < %s -mcpu=scorpion (all possible and exclusion scenarios)
Are there any pointers on creating the IAS testing ?
There are two paths:
- directly to object file:
$ llc -filetype=obj test.ll | llvm-objdump -d | FileCheck
; CHECK: whatever
- from asm file into object:
$ llc -filetype=asm test.ll | llvm-mc -filetype=obj | llvm-objdump -d | FileCheck
; CHECK: whatever
cheers,
--renato
I have updated the patch with the support for krait hwdiv. ".arch_extension" is used to compute the feature bits for krait.
I have also updated a test case testing both the paths suggested by Renato
Hi Sumanth,
The patch is looking good, thanks!
I'm just wondering if you could end up having a Krait with HDIV only in ARM and chose Thumb2. If so, than my comments need addressing.
cheers,
--renato
lib/Target/ARM/ARMAsmPrinter.cpp | ||
---|---|---|
682 ↗ | (On Diff #19282) | shouldn't you check here based on the instruction set you're using? Something like: if (Subtarget->isKrait() && ( Subtarget->hasDivide() || (!Subtarget->isThumb() && Subtarget->hasDivideInARMMode()) ) To make sure we don't turn it on when it's thumb and it only has div on ARM. |
test/CodeGen/ARM/krait-cpu-div-attribute.ll | ||
11 ↗ | (On Diff #19282) | If the above change is needed (checking for ISA on hdiv), then we'll need the corresponding lines here. |
If you could upload more context in the future with your patches, they're a little light.
One comment inline.
Ah. Thanks.
Here you go.
lib/Target/ARM/ARMAsmPrinter.cpp | ||
---|---|---|
682 ↗ | (On Diff #19282) | Using subtargets here is not going to be allowed as soon as I can separate the code out so I'd prefer you come up with another way of figuring out the ISA here. Honestly a loop over all functions in the module and collecting cpu information is probably how we're going to need to go and should be simple. I'm not sure how ARM attribute merging works between functions so if someone could detail that it would be appreciated. |
lib/Target/ARM/ARMAsmPrinter.cpp | ||
---|---|---|
682 ↗ | (On Diff #19282) | ARM has no function specific attribute in EABI. The only thing we do is in the assembler just for the sake of accepting otherwise invalid instructions (bump up support) for the rare case where you're pretty sure no one will call that function without support for that instruction. This has mainly two users: ifunc and unwinders. The point here is to work around a GAS deficiency in representing "krait" as an A9+DIV in a *global* context. So, your function specific attribute will either not exist, or be replicated to all functions, whatever is easier for you. Regarding getting the ISA, I was wrong, and we should use the build attributes anyway. |
lib/Target/ARM/ARMAsmPrinter.cpp | ||
---|---|---|
682 ↗ | (On Diff #19282) | Guys, I am bit confused here what needs to be done. Renato, "hasDivide()" checks for thumb2 and "hasDivideInARMMode()" checks for arm mode, the two modes where hwdiv is allowed. ARMAsmPrinter.cpp has loads of references to Subtarget. Wouldn't it be a good idea to clean them in a single go ? |
Just a couple of minor points:
include/llvm/MC/MCStreamer.h | ||
---|---|---|
142 | I think this either needs a generic implementation, or (probably better for now) moving to ARMELFStreamer.cpp entirely. OK, so it's not called, but | |
lib/Target/ARM/ARMAsmPrinter.cpp | ||
644 ↗ | (On Diff #19282) | Any news on this, by the way? It's rather a horrific hack to have to carry, and it only seems to be getting worse. |
include/llvm/MC/MCStreamer.h | ||
---|---|---|
142 | ARMELFStreamer? But this is assembly only... | |
lib/Target/ARM/ARMAsmPrinter.cpp | ||
644 ↗ | (On Diff #19282) | You know, I've been thinking... With the number of third-party ARM CPUs out there, maybe it would be a better model to emit .cpu as a core ARM name, and use .arch_extension to all little differences, for all other cores. Of course, "if (Krait)" is not what I'm suggesting, but maybe a spec of each CPU somewhere, possible extracted from TableGen files, could go a long way of doing this right and transparent... |
682 ↗ | (On Diff #19282) |
That's what I meant, so it should be ok.
Yes, I don't think this is work for this patch. |
include/llvm/MC/MCStreamer.h | ||
---|---|---|
142 | Yep, but it's essentially en ELF-dialect assembly feature so the AsmStreamer seems to live in the same file. |
include/llvm/MC/MCStreamer.h | ||
---|---|---|
142 | Ignore my previous comment as I thought I added the member to MCTargetStreamer. / If target foo wants to use this, it should implement 3 classes: |
include/llvm/MC/MCStreamer.h | ||
---|---|---|
142 | Oh bother, looks like I was confused by what classes lived where. I assumed that because it was in MCStreamer.h, the definition belonged to "class MCStreamer". Sorry about that, you can ignore my comment. |
include/llvm/MC/MCStreamer.h | ||
---|---|---|
142 | No problem. Your comments made me go through MCStreamer more deeper. | |
lib/Target/ARM/ARMAsmPrinter.cpp | ||
644 ↗ | (On Diff #19282) |
This is exactly what I am trying to implement here.
I second your opinion except that I have no clue on how to implement it. This is my first patch to LLVM :). I need a lot more time to go through most of the components of LLVM |
Tim, Eric, any more comments?
I think for what it is, the patch is good to go. The sub-target refactoring is already covered by a bug I own (sub-target description classes).
cheers,
--renato
lib/Target/ARM/ARMAsmPrinter.cpp | ||
---|---|---|
644 ↗ | (On Diff #19282) | Sorry, I didn't mean this patch should have that refactoring, just that this technique isn't pointing us in the wrong direction. The idea is to ultimately remove all isKrait() and similar checks from the back-end, but this is not possible today. I agree with Tim that the new code looks it's going in the wrong direction, but in the grand scheme of things, it may not. Plus, that refactoring will have to be done more thoroughly at once, from the table-gen side. |
Renato,
I will wait for a day to see if either Tim or Eric responds. If you can approve this, I can merge.
Couple of comments/questions:
a) Formatting, please run this through clang-format.
b) The attribute changes on the testcases, what's going on there?
c) If the krait always has hardware divide why both conditionals after?
d) It seems that the .cpu directive for the krait cpu is orthogonal to the arch_extension part of this patch.
e) It doesn't seem that the arch_extension stuff is wired into the object emitter? What is supposed to happen there?
-eric
Krait is currently modelled as A15 because it's A9+Div, but it's closer to A9 than A15, and that generates codegen issues.
There is no way of telling an external assembler that the CPU is A9+Div other than adding two directives (.cpu + .arch_extension), since GAS doesn't support ".cpu krait", and I'm not sure it should, TBH, since that's the whole point of the .arch_extension directive.
c) If the krait always has hardware divide why both conditionals after?
Because of "-mattr=-hwdiv,-hwdiv-arm".
d) It seems that the .cpu directive for the krait cpu is orthogonal to the arch_extension part of this patch.
Almost... :)
.arch_extension is needed to help GAS understand that krait is A9+Div, that's why it's in the same patch. Without it, the original patch looked completely useless. This merge was actually my fault, if you feel strongly, it should be pretty safe to split the .arch_extension from the krait changes.
e) It doesn't seem that the arch_extension stuff is wired into the object emitter? What is supposed to happen there?
The object emitter already knows that Krait is A9+Div, so the Div instructions get emitted correctly. The directive is *just* for the sake of GAS allowing Divs to be emitted.
Patch rebased to tip.
Patch is ran through clang-format.
Thanks for the clean explanation Renato.
d) It seems that the .cpu directive for the krait cpu is orthogonal to the arch_extension part of this patch.
Almost... :)
>.arch_extension is needed to help GAS understand that krait is A9+Div, that's why it's in the same patch. Without it, the original patch looked completely useless. This merge was actually my fault, if you feel strongly, it should be pretty safe to split the .arch_extension from the krait changes
I agree the changes are orthogonal, but with out the use case scenario, the first patch doesn't make any sense.
I started with splitting the patches and was convinced by Tim and Renato to merge them.
If you insist, I will split them as long as other reviewers agree with it. Note that one of the patches will go with out a unit test.
Ahh!! I just checked my email.
I am surprised to see the comments in email conversation but not here.
I will go through emails and do the necessary.
OK, so the split should be:
Patch 1: .cpu directive changes for krait
Patch 2: adding the .arch_extension directive and using it for krait.
-eric
lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | ||
---|---|---|
254 | Can you change this to be an enum, like CPU/FPU? |
lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | ||
---|---|---|
254 | Do you expect me to define a ".h" and ".def" files ? |
Excellent, that's exactly what I was talking about. :)
Some tests for this one will be in the next patch. You could hint that on the commit message.
Sorry for having taken so long. LGTM.
cheers,
--renato
I think this either needs a generic implementation, or (probably better for now) moving to ARMELFStreamer.cpp entirely. OK, so it's not called, but