forked from OSchip/llvm-project
Basic fast-isel of extractvalue. Not too helpful on its own, given the IR clang generates for cases like this, but it should become more useful soon.
llvm-svn: 131417
This commit is contained in:
parent
9c876bf937
commit
9ac944774f
|
@ -343,6 +343,8 @@ private:
|
|||
|
||||
bool SelectCast(const User *I, unsigned Opcode);
|
||||
|
||||
bool SelectExtractValue(const User *I);
|
||||
|
||||
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
|
||||
/// Emit code to ensure constants are copied into registers when needed.
|
||||
/// Remember the virtual registers that need to be added to the Machine PHI
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "llvm/Instructions.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/CodeGen/Analysis.h"
|
||||
#include "llvm/CodeGen/FastISel.h"
|
||||
#include "llvm/CodeGen/FunctionLoweringInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
|
@ -838,6 +839,44 @@ FastISel::SelectFNeg(const User *I) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FastISel::SelectExtractValue(const User *U) {
|
||||
const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U);
|
||||
if (!U)
|
||||
return false;
|
||||
|
||||
// Make sure we only try to handle extracts with a legal result.
|
||||
EVT RealVT = TLI.getValueType(EVI->getType(), /*AllowUnknown=*/true);
|
||||
if (!RealVT.isSimple())
|
||||
return false;
|
||||
MVT VT = RealVT.getSimpleVT();
|
||||
if (!TLI.isTypeLegal(VT))
|
||||
return false;
|
||||
|
||||
const Value *Op0 = EVI->getOperand(0);
|
||||
const Type *AggTy = Op0->getType();
|
||||
|
||||
// Get the base result register.
|
||||
unsigned ResultReg;
|
||||
DenseMap<const Value *, unsigned>::iterator I = FuncInfo.ValueMap.find(Op0);
|
||||
if (I != FuncInfo.ValueMap.end())
|
||||
ResultReg = I->second;
|
||||
else
|
||||
ResultReg = FuncInfo.InitializeRegForValue(Op0);
|
||||
|
||||
// Get the actual result register, which is an offset from the base register.
|
||||
unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->idx_begin(), EVI->idx_end());
|
||||
|
||||
SmallVector<EVT, 4> AggValueVTs;
|
||||
ComputeValueVTs(TLI, AggTy, AggValueVTs);
|
||||
|
||||
for (unsigned i = 0; i < VTIndex; i++)
|
||||
ResultReg += TLI.getNumRegisters(FuncInfo.Fn->getContext(), AggValueVTs[i]);
|
||||
|
||||
UpdateValueMap(EVI, ResultReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
FastISel::SelectOperator(const User *I, unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
|
@ -942,6 +981,9 @@ FastISel::SelectOperator(const User *I, unsigned Opcode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
case Instruction::ExtractValue:
|
||||
return SelectExtractValue(I);
|
||||
|
||||
case Instruction::PHI:
|
||||
llvm_unreachable("FastISel shouldn't visit PHI nodes!");
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 | FileCheck %s
|
||||
|
||||
%struct.x = type { i64, i64 }
|
||||
declare %struct.x @f()
|
||||
|
||||
define void @test1(i64*) nounwind ssp {
|
||||
%2 = tail call %struct.x @f() nounwind
|
||||
%3 = extractvalue %struct.x %2, 0
|
||||
%4 = add i64 %3, 10
|
||||
store i64 %4, i64* %0
|
||||
ret void
|
||||
; CHECK: test1:
|
||||
; CHECK: callq _f
|
||||
; CHECK-NEXT: addq $10, %rax
|
||||
}
|
||||
|
||||
define void @test2(i64*) nounwind ssp {
|
||||
%2 = tail call %struct.x @f() nounwind
|
||||
%3 = extractvalue %struct.x %2, 1
|
||||
%4 = add i64 %3, 10
|
||||
store i64 %4, i64* %0
|
||||
ret void
|
||||
; CHECK: test2:
|
||||
; CHECK: callq _f
|
||||
; CHECK-NEXT: addq $10, %rdx
|
||||
}
|
Loading…
Reference in New Issue