summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [GlobalISel][ARM] Adding HPR and QPR regclasses to FPRB regbankRoman Tereshin2018-05-231-0/+2
| | | | | | | | | | | Also bringing ARMRegisterBankInfo::getRegBankFromRegClass implementation up to speed with the *.td-definition. Reviewed By: qcolombet Differential Revision: https://reviews.llvm.org/D43982 llvm-svn: 333056
* Rename DEBUG macro to LLVM_DEBUG.Nicola Zaghen2018-05-141-21/+24
| | | | | | | | | | | | | | | | The DEBUG() macro is very generic so it might clash with other projects. The renaming was done as follows: - git grep -l 'DEBUG' | xargs sed -i 's/\bDEBUG\s\?(/LLVM_DEBUG(/g' - git diff -U0 master | ../clang/tools/clang-format/clang-format-diff.py -i -p1 -style LLVM - Manual change to APInt - Manually chage DOCS as regex doesn't match it. In the transition period the DEBUG() macro is still present and aliased to the LLVM_DEBUG() one. Differential Revision: https://reviews.llvm.org/D43624 llvm-svn: 332240
* TargetMachine: Add address space to getPointerSizeMatt Arsenault2018-03-141-2/+2
| | | | llvm-svn: 327467
* [ARM GlobalISel] Select G_PHIDiana Picus2018-01-041-16/+33
| | | | | | | | Select G_PHI to PHI and manually constrain the result register. This is very similar to how COPY is handled, so extract and reuse some of that code. llvm-svn: 321797
* [ARM GlobalISel] Fix selection of pointer constantsDiana Picus2018-01-041-8/+26
| | | | | | | | | | | | | | | | | | | | We used to handle G_CONSTANT with pointer type by forcing the type of the result register to s32 and then letting TableGen handle it. Unfortunately, setting the type only works for generic virtual registers, that haven't yet been constrained to a register class (e.g. those used only by a COPY later on). If the result register has already been constrained as a use of a previously selected instruction, then setting the type will assert. It would be nice to be able to teach TableGen to select pointer constants the same as integer constants, but since it's such an edge case (at the moment the only pointer constant that we're generally interested in is 0, and that is mostly used for comparisons and selects, which are also not supported by TableGen) it's probably not worth the effort right now. Instead, handle pointer constants with some trivial handwritten code. llvm-svn: 321793
* [ARM GlobalISel] Support G_INTTOPTR and G_PTRTOINT for s32Diana Picus2017-12-221-0/+22
| | | | | | | Mark conversions between pointers and 32-bit scalars as legal, map them to the GPR and select to a simple COPY. llvm-svn: 321356
* [ARM GlobalISel] Support pointer constantsDiana Picus2017-12-221-1/+10
| | | | | | | | | | Pointer constants are pretty rare, since we usually represent them as integer constants and then cast to pointer. One notable exception is the null pointer constant, which is represented directly as a G_CONSTANT 0 with pointer type. Mark it as legal and make sure it is selected like any other integer constant. llvm-svn: 321354
* [ARM GlobalISel] Fix assertion in RegBankSelectDiana Picus2017-12-201-0/+25
| | | | | | | | | | | | | | | | | | | | We get an assertion in RegBankSelect for code along the lines of my_32_bit_int = my_64_bit_int, which tends to translate into a 64-bit load, followed by a G_TRUNC, followed by a 32-bit store. This appears in a couple of places in the test-suite. At the moment, the legalizer doesn't distinguish between integer and floating point scalars, so a 64-bit load will be marked as legal for targets with VFP, and so will the rest of the sequence, leading to a slightly bizarre G_TRUNC reaching RegBankSelect. Since the current support for 64-bit integers is rather immature, this patch works around the issue by explicitly handling this case in RegBankSelect and InstructionSelect. In the future, we may want to revisit this decision and make sure 64-bit integer loads are narrowed before reaching RegBankSelect. llvm-svn: 321165
* Revert r319691: [globalisel][tablegen] Split atomic load/store into separate ↵Daniel Sanders2017-12-051-0/+6
| | | | | | | | opcode and enable for AArch64. Some concerns were raised with the direction. Revert while we discuss it and look into an alternative llvm-svn: 319739
* [globalisel][tablegen] Split atomic load/store into separate opcode and ↵Daniel Sanders2017-12-041-6/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | enable for AArch64. This patch splits atomics out of the generic G_LOAD/G_STORE and into their own G_ATOMIC_LOAD/G_ATOMIC_STORE. This is a pragmatic decision rather than a necessary one. Atomic load/store has little in implementation in common with non-atomic load/store. They tend to be handled very differently throughout the backend. It also has the nice side-effect of slightly improving the common-case performance at ISel since there's no longer a need for an atomicity check in the matcher table. All targets have been updated to remove the atomic load/store check from the G_LOAD/G_STORE path. AArch64 has also been updated to mark G_ATOMIC_LOAD/G_ATOMIC_STORE legal. There is one issue with this patch though which also affects the extending loads and truncating stores. The rules only match when an appropriate G_ANYEXT is present in the MIR. For example, (G_ATOMIC_STORE (G_TRUNC:s16 (G_ANYEXT:s32 (G_ATOMIC_LOAD:s16 X)))) will match but: (G_ATOMIC_STORE (G_ATOMIC_LOAD:s16 X)) will not. This shouldn't be a problem at the moment, but as we get better at eliminating extends/truncates we'll likely start failing to match in some cases. The current plan is to fix this in a patch that changes the representation of extending-load/truncating-store to allow the MMO to describe a different type to the operation. llvm-svn: 319691
* [ARM GlobalISel] Fix selecting G_BRCONDDiana Picus2017-11-291-1/+1
| | | | | | | | | | | | | When lowering a G_BRCOND, we generate a TSTri of the condition against 1, which sets the flags, and then a Bcc which branches based on the value of the flags. Unfortunately, we were using the wrong condition code to check whether we need to branch (EQ instead of NE), which caused all our branches to do the opposite of what they were intended to do. This patch fixes the issue by using the correct condition code. llvm-svn: 319313
* [globalisel][tablegen] Generate rule coverage and use it to identify ↵Daniel Sanders2017-11-161-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | untested rules Summary: This patch adds a LLVM_ENABLE_GISEL_COV which, like LLVM_ENABLE_DAGISEL_COV, causes TableGen to instrument the generated table to collect rule coverage information. However, LLVM_ENABLE_GISEL_COV goes a bit further than LLVM_ENABLE_DAGISEL_COV. The information is written to files (${CMAKE_BINARY_DIR}/gisel-coverage-* by default). These files can then be concatenated into ${LLVM_GISEL_COV_PREFIX}-all after which TableGen will read this information and use it to emit warnings about untested rules. This technique could also be used by SelectionDAG and can be further extended to detect hot rules and give them priority over colder rules. Usage: * Enable LLVM_ENABLE_GISEL_COV in CMake * Build the compiler and run some tests * cat gisel-coverage-[0-9]* > gisel-coverage-all * Delete lib/Target/*/*GenGlobalISel.inc* * Build the compiler Known issues: * ${LLVM_GISEL_COV_PREFIX}-all must be generated as a manual step due to a lack of a portable 'cat' command. It should be the concatenation of all ${LLVM_GISEL_COV_PREFIX}-[0-9]* files. * There's no mechanism to discard coverage information when the ruleset changes Depends on D39742 Reviewers: ab, qcolombet, t.p.northover, aditya_nandakumar, rovka Reviewed By: rovka Subscribers: vsk, arsenm, nhaehnle, mgorny, kristof.beyls, javed.absar, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D39747 llvm-svn: 318356
* [ARM GlobalISel] Remove C++ code for G_CONSTANTDiana Picus2017-11-141-22/+0
| | | | | | | | | | Get rid of the handwritten instruction selector code for handling G_CONSTANT. This code wasn't checking all the preconditions correctly anyway, so it's better to leave it to TableGen, which can handle at least some cases correctly (e.g. MOVi, MOVi16, folding into binary operations). Also add tests to cover those cases. llvm-svn: 318146
* [arm] Fix Unnecessary reloads from GOT.Evgeniy Stepanov2017-11-131-1/+5
| | | | | | | | | | | | Summary: This fixes PR35221. Use pseudo-instructions to let MachineCSE hoist global address computation. Subscribers: aemerson, javed.absar, kristof.beyls, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D39871 llvm-svn: 318081
* InstructionSelectorImpl.h: Modularize/remove ODR violations by using a ↵David Blaikie2017-10-261-2/+2
| | | | | | static member function to expose the debug name llvm-svn: 316715
* [ARM] GlobalISel: Select shiftsDiana Picus2017-10-061-0/+16
| | | | | | | | | Unfortunately TableGen doesn't handle this yet: Unable to deduce gMIR opcode to handle Src (which is a leaf). Just add some temporary hand-written code to generate the proper MOVsr. llvm-svn: 315071
* [ARM] GlobalISel: Minor cleanups in inst selectorDiana Picus2017-09-051-11/+10
| | | | | | | | Use the STI member of ARMInstructionSelector instead of TII.getSubtarget() and also make use of STI's methods instead of checking the object format manually. llvm-svn: 312522
* [ARM] GlobalISel: Support global variables for RWPIDiana Picus2017-09-051-15/+51
| | | | | | | | | In RWPI code, globals that are not read-only are accessed relative to the SB register (R9). This is achieved by explicitly generating an ADD instruction between SB and an offset that we either load from a constant pool or movw + movt into a register. llvm-svn: 312521
* [ARM] GlobalISel: Support ROPI global variablesDiana Picus2017-09-011-2/+14
| | | | | | | In the ROPI relocation model, read-only variables are accessed relative to the PC. We use the (MOV|LDRLIT)_ga_pcrel pseudoinstructions for this. llvm-svn: 312323
* [ARM] GlobalISel: Select globals in PIC modeDiana Picus2017-08-291-5/+22
| | | | | | | | | | | | | | Support the selection of G_GLOBAL_VALUE in the PIC relocation model. For simplicity we use the same pseudoinstructions for both Darwin and ELF: (MOV|LDRLIT)_ga_pcrel(_ldr). This is new for ELF, so it requires a small update to the ARM pseudo expansion pass to make sure it adds the correct constant pool modifier and add-current-address in the case of ELF. Differential Revision: https://reviews.llvm.org/D36507 llvm-svn: 311992
* [GlobalISel] Make GlobalISel a non-optional library.Quentin Colombet2017-08-031-4/+0
| | | | | | | | With this change, the GlobalISel library gets always built. In particular, this is not possible to opt GlobalISel out of the build using the LLVM_BUILD_GLOBAL_ISEL variable any more. llvm-svn: 309990
* [ARM] GlobalISel: Select simple G_GLOBAL_VALUE instructionsDiana Picus2017-08-031-0/+57
| | | | | | | | | | | | | Add support in the instruction selector for G_GLOBAL_VALUE for ELF and MachO for the static relocation model. We don't handle Windows yet because that's Thumb-only, and we don't handle Thumb in general at the moment. Support for PIC, ROPI, RWPI and TLS will be added in subsequent commits. Differential Revision: https://reviews.llvm.org/D35883 llvm-svn: 309927
* Re-commit: r309094 [globalisel][tablegen] Fuse the generated tables together.Daniel Sanders2017-07-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Now that we have control flow in place, fuse the per-rule tables into a single table. This is a compile-time saving at this point. However, this will also enable the optimization of a table so that similar instructions can be tested together, reducing the time spent on the matching the code. This is NFC in terms of externally visible behaviour but some internals have changed slightly. State.MIs is no longer reset between each rule that is attempted because it's not necessary to do so. As a consequence of this the restriction on the order that instructions are added to State.MIs has been relaxed to only affect recorded instructions that require new elements to be added to the vector. GIM_RecordInsn can now write to any element from 1 to State.MIs.size() instead of just State.MIs.size(). The compile-time regressions from the last commit were caused by the ARM target including a non-const variable (zero_reg) in the table and therefore generating an initializer for it. That variable is now const. Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar Reviewed By: rovka Subscribers: kristof.beyls, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D35681 llvm-svn: 309264
* [ARM] GlobalISel: Support G_BRCONDDiana Picus2017-07-141-0/+23
| | | | | | | | | | | | Insert a TSTri to set the flags and a Bcc to branch based on their values. This is a bit inefficient in the (common) cases where the condition for the branch comes from a compare right before the branch, since we set the flags both as part of the compare lowering and as part of the branch lowering. We're going to live with that until we settle on a principled way to handle this kind of situation, which occurs with other patterns as well (combines might be the way forward here). llvm-svn: 308009
* [ARM] GlobalISel: Simplify inst selector code. NFCDiana Picus2017-07-121-198/+143
| | | | | | | | | | | Refactor CmpHelper into something simpler. It was overkill to use templates for this - instead, use a simple CmpConstants structure to hold the opcodes and other constants that are different when selecting int / float / double comparisons. Also, extract some of the helpers that were in CmpHelper into ARMInstructionSelector and make use of some of them when selecting other things than just compares. llvm-svn: 307766
* [ARM] GlobalISel: Select s64 G_FCMPDiana Picus2017-07-121-3/+38
| | | | | | | Very similar to how we select s32 G_FCMP, the only thing that is different is the exact opcodes that we use. llvm-svn: 307763
* [ARM] GlobalISel: Fixup r307365Diana Picus2017-07-071-11/+10
| | | | | | | Rename member DebugLoc -> DbgLoc (so it doesn't conflict with the class name). llvm-svn: 307366
* [ARM] GlobalISel: Select hard G_FCMP for s32Diana Picus2017-07-071-63/+234
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We lower to a sequence consisting of: - MOVi 0 into a register - VCMPS to do the actual comparison and set the VFP flags - FMSTAT to move the flags out of the VFP unit - MOVCCi to either use the "zero register" that we have previously set with the MOVi, or move 1 into the result register, based on the values of the flags As was the case with soft-float, for some predicates (one, ueq) we actually need two comparisons instead of just one. When that happens, we generate two VCMPS-FMSTAT-MOVCCi sequences and chain them by means of using the result of the first MOVCCi as the "zero register" for the second one. This is a bit overkill, since one comparison followed by two non-flag-setting conditional moves should be enough. In any case, the backend manages to CSE one of the comparisons away so it doesn't matter much. Note that unlike SelectionDAG and FastISel, we always use VCMPS, and not VCMPES. This makes the code a lot simpler, and it also seems correct since the LLVM Lang Ref defines simple true/false returns if the operands are QNaN's. For SNaN's, even VCMPS throws an Invalid Operand exception, so they won't be slipping through unnoticed. Implementation-wise, this introduces a template so we can share the same code that we use for handling integer comparisons, since the only differences are in the details (exact opcodes to be used etc). Hopefully this will be easy to extend to s64 G_FCMP. llvm-svn: 307365
* [globalisel][tablegen] Partially fix compile-time regressions by converting ↵Daniel Sanders2017-07-041-0/+2
| | | | | | | | | | | | | | | | | | | | | | matcher to state-machine(s) Summary: Replace the matcher if-statements for each rule with a state-machine. This significantly reduces compile time, memory allocations, and cumulative memory allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is recommitted. The following patches will expand on this further to fully fix the regressions. Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar Reviewed By: ab Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D33758 llvm-svn: 307079
* [ARM] GlobalISel: Support G_SELECT for i32Diana Picus2017-06-271-0/+50
| | | | | | | | | | * Mark as legal for (s32, i1, s32, s32) * Map everything into GPRs * Select to two instructions: a CMP of the condition against 0, to set the flags, and a MOVCCr to select between the two inputs based on the flags that we've just set llvm-svn: 306382
* [ARM] GlobalISel: Support G_ICMP for i32 and pointersDiana Picus2017-06-191-0/+105
| | | | | | | | | | | | | | Add support throughout the pipeline: - mark as legal for s32 and pointers - map to GPRs - lower to a sequence of instructions, which moves 0 or 1 into the result register based on the flags set by a CMPrr We have copied from FastISel a helper function which maps CmpInst predicates into ARMCC codes. Ideally, we should be able to move it somewhere that both FastISel and GlobalISel can use. llvm-svn: 305672
* [ARM] GlobalISel: Purge G_SEQUENCEDiana Picus2017-06-071-36/+34
| | | | | | | | | | | | | | | | | According to the commit message from r296921, G_MERGE_VALUES and G_INSERT are to be preferred over G_SEQUENCE. Therefore, stop generating G_SEQUENCE in the ARM backend and remove the code dealing with it. This boils down to the code breaking up double values for the soft float calling convention. Use G_MERGE_VALUES + G_UNMERGE_VALUES instead of G_SEQUENCE + G_EXTRACT for it. This maps very nicely to VMOVDRR + VMOVRRD and simplifies the code in the instruction selector. There's one occurence of G_SEQUENCE left in arm-irtranslator.ll, but that is part of the target-independent code for translating constant structs. Therefore, it is beyond the scope of this commit. llvm-svn: 304902
* Reland r303247: [ARM] GlobalISel: Remove dead instruction selection codeDiana Picus2017-05-171-15/+0
| | | | | | | | It only failed on llvm-clang-x86_64-expensive-checks-win, probably because the TableGen stuff hasn't been regenerated. Requires a clean build. llvm-svn: 303252
* Revert "[ARM] GlobalISel: Remove dead instruction selection code"Diana Picus2017-05-171-0/+15
| | | | | | | This reverts commit r303247 because the tests are failing on some bots. Sorry! llvm-svn: 303249
* [ARM] GlobalISel: Remove dead instruction selection codeDiana Picus2017-05-171-15/+0
| | | | | | | We can now generate code for selecting G_ADD, G_SUB and G_MUL. Remove the hand-written versions. llvm-svn: 303247
* [ARM][GlobalISel] Support for G_ANYEXTDiana Picus2017-05-111-10/+3
| | | | | | | | | | | | | | G_ANYEXT can be introduced by the legalizer when widening scalars. Add support for it in the register bank info (same mapping as everything else) and in the instruction selector. When selecting it, we treat it as a COPY, just like G_TRUNC. On this occasion we get rid of some assertions in selectCopy so we can reuse it. This shouldn't be a problem at the moment since we're not supporting any complicated cases (e.g. FPR, different register banks). We might want to separate the paths when we do. llvm-svn: 302778
* [ARM GlobalISel] Remove hand-written G_FADD selectionDiana Picus2017-05-091-26/+0
| | | | | | | Remove the code selecting G_FADD - now that TableGen can handle more opcodes, it's not needed anymore. llvm-svn: 302511
* [ARM] GlobalISel: Use TableGen instruction selectorDiana Picus2017-05-021-15/+43
| | | | | | | | | | | Emit and use the TableGen instruction selector for ARM. At the moment, this allows us to remove the hand-written code for selecting G_SDIV and G_UDIV. Future commits will focus on increasing the code coverage for it and removing more dead code from the current instruction selector. llvm-svn: 301905
* [ARM] GlobalISel: Get rid of ARMInstructionSelector.h. NFC.Diana Picus2017-04-281-1/+24
| | | | | | | | | Declare the ARMInstructionSelector in an anonymous namespace, to make it more in line with the other targets which were migrated to this in r299637 in order to avoid TableGen'erated headers being included in non-GlobalISel builds. llvm-svn: 301632
* [ARM] GlobalISel: Support G_(S|U)DIV for s32Diana Picus2017-04-241-0/+10
| | | | | | | | | Add support for both targets with hardware division and without. For hardware division we have to add support throughout the pipeline (legalizer, reg bank select, instruction select). For targets without hardware division, we only need to mark it as a libcall. llvm-svn: 301164
* [ARM] GlobalISel: Select G_CONSTANT with CImm operandsDiana Picus2017-04-241-0/+12
| | | | | | | | | | | | | | When selecting a G_CONSTANT to a MOVi, we need the value to be an Imm operand. We used to just leave the G_CONSTANT operand unchanged, which works in some cases (such as the GEP offsets that we create when referring to stack slots). However, in many other places the G_CONSTANTs are created with CImm operands. This patch makes sure to handle those as well, and to error out gracefully if in the end we don't end up with an Imm operand. Thanks to Oliver Stannard for reporting this issue. llvm-svn: 301162
* [ARM] GlobalISel: Add support for G_TRUNCDiana Picus2017-04-211-6/+25
| | | | | | | | Select them as copies. We only select if both the source and the destination are on the same register bank, so this shouldn't cause any trouble. llvm-svn: 300971
* [ARM] GlobalISel: Add support for G_MULDiana Picus2017-04-191-0/+10
| | | | | | | | Support G_MUL, very similar to G_ADD and G_SUB. The only difference is in the instruction selector, where we have to select either MUL or MULv5 depending on the target. llvm-svn: 300665
* [ARM] GlobalISel: Add support for G_SUBDiana Picus2017-04-181-0/+4
| | | | | | | Support G_SUB throughout the GlobalISel pipeline. It is exactly the same as G_ADD, nothing fancy. llvm-svn: 300546
* GlobalISel: restrict G_EXTRACT instruction to just one operand.Tim Northover2017-03-061-12/+8
| | | | | | | A bit more painful than G_INSERT because it was more widely used, but this should simplify the handling of extract operations in most locations. llvm-svn: 297100
* [ARM] GlobalISel: Select 32-bit G_CONSTANTDiana Picus2017-02-281-0/+11
| | | | | | Put it into a register by means of a MOVi. llvm-svn: 296471
* [ARM] GlobalISel: Select G_GEPDiana Picus2017-02-281-0/+1
| | | | | | At this point, G_GEP is just an add, so we treat it exactly like a G_ADD. llvm-svn: 296462
* [ARM] GlobalISel: Select G_STOREDiana Picus2017-02-241-16/+20
| | | | | | Same as selecting G_LOAD. llvm-svn: 296122
* [ARM] GlobalISel: Don't select atomic loadsDiana Picus2017-02-201-0/+6
| | | | | | | | | | | | | | | There used to be a check in the IRTranslator that prevented us from having to deal with atomic loads/stores. That check has been removed in r294993 and the AArch64 backend was updated accordingly. This commit does the same thing for the ARM backend. In general, in the ARM backend we introduce fences during the atomic expand pass, so we don't have to worry about atomics, *except* for the 32-bit ARMv8 target, which handles atomics more like AArch64. Since we don't want to worry about that yet, just bail out of instruction selection if we find any atomic loads. llvm-svn: 295662
* [ARM] GlobalISel: Clean up some helpersDiana Picus2017-02-171-19/+24
| | | | | | | Return invalid opcodes when some of the helpers in the instruction selection pass can't handle a given combination. llvm-svn: 295446
OpenPOWER on IntegriCloud