Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
swiftshader
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
swiftshader
Commits
6d47bcdc
Commit
6d47bcdc
authored
Sep 17, 2015
by
Andrew Scull
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor Hi and Lo out of Variable.
BUG= R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/1326013002
.
parent
c49eeae4
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
168 additions
and
183 deletions
+168
-183
IceCfg.cpp
src/IceCfg.cpp
+15
-0
IceCfg.h
src/IceCfg.h
+2
-0
IceInst.cpp
src/IceInst.cpp
+2
-0
IceOperand.h
src/IceOperand.h
+72
-23
IceTargetLowering.h
src/IceTargetLowering.h
+3
-0
IceTargetLoweringARM32.cpp
src/IceTargetLoweringARM32.cpp
+27
-63
IceTargetLoweringARM32.h
src/IceTargetLoweringARM32.h
+4
-3
IceTargetLoweringMIPS32.h
src/IceTargetLoweringMIPS32.h
+4
-0
IceTargetLoweringX8632.cpp
src/IceTargetLoweringX8632.cpp
+3
-4
IceTargetLoweringX86Base.h
src/IceTargetLoweringX86Base.h
+4
-15
IceTargetLoweringX86BaseImpl.h
src/IceTargetLoweringX86BaseImpl.h
+32
-75
No files found.
src/IceCfg.cpp
View file @
6d47bcdc
...
@@ -75,6 +75,16 @@ void Cfg::swapNodes(NodeList &NewNodes) {
...
@@ -75,6 +75,16 @@ void Cfg::swapNodes(NodeList &NewNodes) {
Nodes
[
I
]
->
resetIndex
(
I
);
Nodes
[
I
]
->
resetIndex
(
I
);
}
}
template
<>
Variable
*
Cfg
::
makeVariable
<
Variable
>
(
Type
Ty
)
{
SizeT
Index
=
Variables
.
size
();
Variable
*
Var
=
Target
->
shouldSplitToVariable64On32
(
Ty
)
?
Variable64On32
::
create
(
this
,
Ty
,
Index
)
:
Variable
::
create
(
this
,
Ty
,
Index
);
Variables
.
push_back
(
Var
);
return
Var
;
}
void
Cfg
::
addArg
(
Variable
*
Arg
)
{
void
Cfg
::
addArg
(
Variable
*
Arg
)
{
Arg
->
setIsArg
();
Arg
->
setIsArg
();
Args
.
push_back
(
Arg
);
Args
.
push_back
(
Arg
);
...
@@ -175,6 +185,11 @@ void Cfg::translate() {
...
@@ -175,6 +185,11 @@ void Cfg::translate() {
}
}
TimerMarker
T
(
TimerStack
::
TT_translate
,
this
);
TimerMarker
T
(
TimerStack
::
TT_translate
,
this
);
// Create the Hi and Lo variables where a split was needed
for
(
Variable
*
Var
:
Variables
)
if
(
auto
Var64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Var
))
Var64On32
->
initHiLo
(
this
);
dump
(
"Initial CFG"
);
dump
(
"Initial CFG"
);
if
(
getContext
()
->
getFlags
().
getEnableBlockProfile
())
{
if
(
getContext
()
->
getFlags
().
getEnableBlockProfile
())
{
...
...
src/IceCfg.h
View file @
6d47bcdc
...
@@ -290,6 +290,8 @@ public:
...
@@ -290,6 +290,8 @@ public:
static
void
TlsInit
()
{
ICE_TLS_INIT_FIELD
(
CurrentCfg
);
}
static
void
TlsInit
()
{
ICE_TLS_INIT_FIELD
(
CurrentCfg
);
}
};
};
template
<>
Variable
*
Cfg
::
makeVariable
<
Variable
>
(
Type
Ty
);
}
// end of namespace Ice
}
// end of namespace Ice
#endif // SUBZERO_SRC_ICECFG_H
#endif // SUBZERO_SRC_ICECFG_H
src/IceInst.cpp
View file @
6d47bcdc
...
@@ -385,6 +385,8 @@ Inst *InstPhi::lower(Cfg *Func) {
...
@@ -385,6 +385,8 @@ Inst *InstPhi::lower(Cfg *Func) {
Variable
*
NewSrc
=
Func
->
makeVariable
(
Dest
->
getType
());
Variable
*
NewSrc
=
Func
->
makeVariable
(
Dest
->
getType
());
if
(
BuildDefs
::
dump
())
if
(
BuildDefs
::
dump
())
NewSrc
->
setName
(
Func
,
Dest
->
getName
(
Func
)
+
"_phi"
);
NewSrc
->
setName
(
Func
,
Dest
->
getName
(
Func
)
+
"_phi"
);
if
(
auto
*
NewSrc64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
NewSrc
))
NewSrc64On32
->
initHiLo
(
Func
);
this
->
Dest
=
NewSrc
;
this
->
Dest
=
NewSrc
;
return
InstAssign
::
create
(
Func
,
Dest
,
NewSrc
);
return
InstAssign
::
create
(
Func
,
Dest
,
NewSrc
);
}
}
...
...
src/IceOperand.h
View file @
6d47bcdc
...
@@ -43,6 +43,7 @@ public:
...
@@ -43,6 +43,7 @@ public:
kConst_Target
,
// leave space for target-specific constant kinds
kConst_Target
,
// leave space for target-specific constant kinds
kConst_Max
=
kConst_Target
+
MaxTargetKinds
,
kConst_Max
=
kConst_Target
+
MaxTargetKinds
,
kVariable
,
kVariable
,
kVariable64On32
,
kVariable_Target
,
// leave space for target-specific variable kinds
kVariable_Target
,
// leave space for target-specific variable kinds
kVariable_Max
=
kVariable_Target
+
MaxTargetKinds
,
kVariable_Max
=
kVariable_Target
+
MaxTargetKinds
,
// Target-specific operand classes use kTarget as the starting point for
// Target-specific operand classes use kTarget as the starting point for
...
@@ -411,7 +412,7 @@ class Variable : public Operand {
...
@@ -411,7 +412,7 @@ class Variable : public Operand {
Variable
(
const
Variable
&
)
=
delete
;
Variable
(
const
Variable
&
)
=
delete
;
Variable
&
operator
=
(
const
Variable
&
)
=
delete
;
Variable
&
operator
=
(
const
Variable
&
)
=
delete
;
enum
RegRequirement
{
enum
RegRequirement
:
uint8_t
{
RR_MayHaveRegister
,
RR_MayHaveRegister
,
RR_MustHaveRegister
,
RR_MustHaveRegister
,
RR_MustNotHaveRegister
,
RR_MustNotHaveRegister
,
...
@@ -424,7 +425,7 @@ public:
...
@@ -424,7 +425,7 @@ public:
SizeT
getIndex
()
const
{
return
Number
;
}
SizeT
getIndex
()
const
{
return
Number
;
}
IceString
getName
(
const
Cfg
*
Func
)
const
;
IceString
getName
(
const
Cfg
*
Func
)
const
;
void
setName
(
Cfg
*
Func
,
const
IceString
&
NewName
)
{
v
irtual
v
oid
setName
(
Cfg
*
Func
,
const
IceString
&
NewName
)
{
// Make sure that the name can only be set once.
// Make sure that the name can only be set once.
assert
(
NameIndex
==
Cfg
::
IdentifierIndexInvalid
);
assert
(
NameIndex
==
Cfg
::
IdentifierIndexInvalid
);
if
(
!
NewName
.
empty
())
if
(
!
NewName
.
empty
())
...
@@ -432,7 +433,7 @@ public:
...
@@ -432,7 +433,7 @@ public:
}
}
bool
getIsArg
()
const
{
return
IsArgument
;
}
bool
getIsArg
()
const
{
return
IsArgument
;
}
void
setIsArg
(
bool
Val
=
true
)
{
IsArgument
=
Val
;
}
v
irtual
v
oid
setIsArg
(
bool
Val
=
true
)
{
IsArgument
=
Val
;
}
bool
getIsImplicitArg
()
const
{
return
IsImplicitArgument
;
}
bool
getIsImplicitArg
()
const
{
return
IsImplicitArgument
;
}
void
setIsImplicitArg
(
bool
Val
=
true
)
{
IsImplicitArgument
=
Val
;
}
void
setIsImplicitArg
(
bool
Val
=
true
)
{
IsImplicitArgument
=
Val
;
}
...
@@ -485,14 +486,6 @@ public:
...
@@ -485,14 +486,6 @@ public:
return
Live
.
overlapsInst
(
Other
->
Live
.
getStart
(),
UseTrimmed
);
return
Live
.
overlapsInst
(
Other
->
Live
.
getStart
(),
UseTrimmed
);
}
}
Variable
*
getLo
()
const
{
return
LoVar
;
}
Variable
*
getHi
()
const
{
return
HiVar
;
}
void
setLoHi
(
Variable
*
Lo
,
Variable
*
Hi
)
{
assert
(
LoVar
==
nullptr
);
assert
(
HiVar
==
nullptr
);
LoVar
=
Lo
;
HiVar
=
Hi
;
}
/// Creates a temporary copy of the variable with a different type. Used
/// Creates a temporary copy of the variable with a different type. Used
/// primarily for syntactic correctness of textual assembly emission. Note
/// primarily for syntactic correctness of textual assembly emission. Note
/// that only basic information is copied, in particular not IsArgument,
/// that only basic information is copied, in particular not IsArgument,
...
@@ -529,28 +522,84 @@ protected:
...
@@ -529,28 +522,84 @@ protected:
/// and validating live ranges. This is usually reserved for the stack
/// and validating live ranges. This is usually reserved for the stack
/// pointer.
/// pointer.
bool
IgnoreLiveness
=
false
;
bool
IgnoreLiveness
=
false
;
/// StackOffset is the canonical location on stack (only if RegNum==NoRegister
RegRequirement
RegRequirement
=
RR_MayHaveRegister
;
/// || IsArgument).
int32_t
StackOffset
=
0
;
/// RegNum is the allocated register, or NoRegister if it isn't
/// RegNum is the allocated register, or NoRegister if it isn't
/// register-allocated.
/// register-allocated.
int32_t
RegNum
=
NoRegister
;
int32_t
RegNum
=
NoRegister
;
/// RegNumTmp is the tentative assignment during register allocation.
/// RegNumTmp is the tentative assignment during register allocation.
int32_t
RegNumTmp
=
NoRegister
;
int32_t
RegNumTmp
=
NoRegister
;
RegRequirement
RegRequirement
=
RR_MayHaveRegister
;
/// StackOffset is the canonical location on stack (only if
/// RegNum==NoRegister || IsArgument).
int32_t
StackOffset
=
0
;
LiveRange
Live
;
LiveRange
Live
;
// LoVar and HiVar are needed for lowering from 64 to 32 bits. When lowering
// from I64 to I32 on a 32-bit architecture, we split the variable into two
// machine-size pieces. LoVar is the low-order machine-size portion, and
// HiVar is the remaining high-order portion.
// TODO: It's wasteful to penalize all variables on all targets this way; use
// a sparser representation. It's also wasteful for a 64-bit target.
Variable
*
LoVar
=
nullptr
;
Variable
*
HiVar
=
nullptr
;
/// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
/// VarsReal (and Operand::Vars) are set up such that Vars[0] == this.
Variable
*
VarsReal
[
1
];
Variable
*
VarsReal
[
1
];
};
};
// Variable64On32 represents a 64-bit variable on a 32-bit architecture. In
// this situation the variable must be split into a low and a high word.
class
Variable64On32
:
public
Variable
{
Variable64On32
()
=
delete
;
Variable64On32
(
const
Variable64On32
&
)
=
delete
;
Variable64On32
&
operator
=
(
const
Variable64On32
&
)
=
delete
;
public
:
static
Variable64On32
*
create
(
Cfg
*
Func
,
Type
Ty
,
SizeT
Index
)
{
return
new
(
Func
->
allocate
<
Variable64On32
>
())
Variable64On32
(
kVariable64On32
,
Ty
,
Index
);
}
void
setName
(
Cfg
*
Func
,
const
IceString
&
NewName
)
override
{
Variable
::
setName
(
Func
,
NewName
);
if
(
LoVar
&&
HiVar
)
{
LoVar
->
setName
(
Func
,
getName
(
Func
)
+
"__lo"
);
HiVar
->
setName
(
Func
,
getName
(
Func
)
+
"__hi"
);
}
}
void
setIsArg
(
bool
Val
=
true
)
override
{
Variable
::
setIsArg
(
Val
);
if
(
LoVar
&&
HiVar
)
{
LoVar
->
setIsArg
(
Val
);
HiVar
->
setIsArg
(
Val
);
}
}
Variable
*
getLo
()
const
{
assert
(
LoVar
!=
nullptr
);
return
LoVar
;
}
Variable
*
getHi
()
const
{
assert
(
HiVar
!=
nullptr
);
return
HiVar
;
}
void
initHiLo
(
Cfg
*
Func
)
{
assert
(
LoVar
==
nullptr
);
assert
(
HiVar
==
nullptr
);
LoVar
=
Func
->
makeVariable
(
IceType_i32
);
HiVar
=
Func
->
makeVariable
(
IceType_i32
);
LoVar
->
setIsArg
(
getIsArg
());
HiVar
->
setIsArg
(
getIsArg
());
LoVar
->
setName
(
Func
,
getName
(
Func
)
+
"__lo"
);
HiVar
->
setName
(
Func
,
getName
(
Func
)
+
"__hi"
);
}
static
bool
classof
(
const
Operand
*
Operand
)
{
OperandKind
Kind
=
Operand
->
getKind
();
return
Kind
==
kVariable64On32
;
}
protected
:
Variable64On32
(
OperandKind
K
,
Type
Ty
,
SizeT
Index
)
:
Variable
(
K
,
Ty
,
Index
)
{
assert
(
typeWidthInBytes
(
Ty
)
==
8
);
}
Variable
*
LoVar
=
nullptr
;
Variable
*
HiVar
=
nullptr
;
};
enum
MetadataKind
{
enum
MetadataKind
{
VMK_Uses
,
/// Track only uses, not defs
VMK_Uses
,
/// Track only uses, not defs
VMK_SingleDefs
,
/// Track uses+defs, but only record single def
VMK_SingleDefs
,
/// Track uses+defs, but only record single def
...
...
src/IceTargetLowering.h
View file @
6d47bcdc
...
@@ -181,6 +181,9 @@ public:
...
@@ -181,6 +181,9 @@ public:
virtual
SizeT
getFrameOrStackReg
()
const
=
0
;
virtual
SizeT
getFrameOrStackReg
()
const
=
0
;
virtual
size_t
typeWidthInBytesOnStack
(
Type
Ty
)
const
=
0
;
virtual
size_t
typeWidthInBytesOnStack
(
Type
Ty
)
const
=
0
;
/// Return whether a 64-bit Variable should be split into a Variable64On32.
virtual
bool
shouldSplitToVariable64On32
(
Type
Ty
)
const
=
0
;
bool
hasComputedFrame
()
const
{
return
HasComputedFrame
;
}
bool
hasComputedFrame
()
const
{
return
HasComputedFrame
;
}
/// Returns true if this function calls a function that has the "returns
/// Returns true if this function calls a function that has the "returns
/// twice" attribute.
/// twice" attribute.
...
...
src/IceTargetLoweringARM32.cpp
View file @
6d47bcdc
...
@@ -528,22 +528,16 @@ void TargetARM32::lowerArguments() {
...
@@ -528,22 +528,16 @@ void TargetARM32::lowerArguments() {
if
(
!
CC
.
I64InRegs
(
&
RegPair
))
if
(
!
CC
.
I64InRegs
(
&
RegPair
))
continue
;
continue
;
Variable
*
RegisterArg
=
Func
->
makeVariable
(
Ty
);
Variable
*
RegisterArg
=
Func
->
makeVariable
(
Ty
);
Variable
*
RegisterLo
=
Func
->
makeVariable
(
IceType_i32
);
auto
*
RegisterArg64On32
=
llvm
::
cast
<
Variable64On32
>
(
RegisterArg
);
Variable
*
RegisterHi
=
Func
->
makeVariable
(
IceType_i32
);
if
(
BuildDefs
::
dump
())
if
(
BuildDefs
::
dump
())
{
RegisterArg64On32
->
setName
(
Func
,
"home_reg:"
+
Arg
->
getName
(
Func
));
RegisterArg
->
setName
(
Func
,
"home_reg:"
+
Arg
->
getName
(
Func
));
RegisterArg64On32
->
initHiLo
(
Func
);
RegisterLo
->
setName
(
Func
,
"home_reg_lo:"
+
Arg
->
getName
(
Func
));
RegisterArg64On32
->
setIsArg
();
RegisterHi
->
setName
(
Func
,
"home_reg_hi:"
+
Arg
->
getName
(
Func
));
RegisterArg64On32
->
getLo
()
->
setRegNum
(
RegPair
.
first
);
}
RegisterArg64On32
->
getHi
()
->
setRegNum
(
RegPair
.
second
);
RegisterLo
->
setRegNum
(
RegPair
.
first
);
RegisterLo
->
setIsArg
();
RegisterHi
->
setRegNum
(
RegPair
.
second
);
RegisterHi
->
setIsArg
();
RegisterArg
->
setLoHi
(
RegisterLo
,
RegisterHi
);
RegisterArg
->
setIsArg
();
Arg
->
setIsArg
(
false
);
Arg
->
setIsArg
(
false
);
Args
[
I
]
=
RegisterArg
;
Args
[
I
]
=
RegisterArg
64On32
;
Context
.
insert
(
InstAssign
::
create
(
Func
,
Arg
,
RegisterArg
));
Context
.
insert
(
InstAssign
::
create
(
Func
,
Arg
,
RegisterArg
));
continue
;
continue
;
}
else
{
}
else
{
...
@@ -582,16 +576,14 @@ void TargetARM32::lowerArguments() {
...
@@ -582,16 +576,14 @@ void TargetARM32::lowerArguments() {
void
TargetARM32
::
finishArgumentLowering
(
Variable
*
Arg
,
Variable
*
FramePtr
,
void
TargetARM32
::
finishArgumentLowering
(
Variable
*
Arg
,
Variable
*
FramePtr
,
size_t
BasicFrameOffset
,
size_t
BasicFrameOffset
,
size_t
&
InArgsSizeBytes
)
{
size_t
&
InArgsSizeBytes
)
{
Variable
*
Lo
=
Arg
->
getLo
();
if
(
auto
*
Arg64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Arg
))
{
Variable
*
Hi
=
Arg
->
getHi
();
Variable
*
Lo
=
Arg64On32
->
getLo
();
Type
Ty
=
Arg
->
getType
();
Variable
*
Hi
=
Arg64On32
->
getHi
();
if
(
Lo
&&
Hi
&&
Ty
==
IceType_i64
)
{
assert
(
Lo
->
getType
()
!=
IceType_i64
);
// don't want infinite recursion
assert
(
Hi
->
getType
()
!=
IceType_i64
);
// don't want infinite recursion
finishArgumentLowering
(
Lo
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
finishArgumentLowering
(
Lo
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
finishArgumentLowering
(
Hi
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
finishArgumentLowering
(
Hi
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
return
;
return
;
}
}
Type
Ty
=
Arg
->
getType
();
InArgsSizeBytes
=
applyStackAlignmentTy
(
InArgsSizeBytes
,
Ty
);
InArgsSizeBytes
=
applyStackAlignmentTy
(
InArgsSizeBytes
,
Ty
);
Arg
->
setStackOffset
(
BasicFrameOffset
+
InArgsSizeBytes
);
Arg
->
setStackOffset
(
BasicFrameOffset
+
InArgsSizeBytes
);
InArgsSizeBytes
+=
typeWidthInBytesOnStack
(
Ty
);
InArgsSizeBytes
+=
typeWidthInBytesOnStack
(
Ty
);
...
@@ -1052,39 +1044,14 @@ void TargetARM32::legalizeStackSlots() {
...
@@ -1052,39 +1044,14 @@ void TargetARM32::legalizeStackSlots() {
}
}
}
}
void
TargetARM32
::
split64
(
Variable
*
Var
)
{
assert
(
Var
->
getType
()
==
IceType_i64
);
Variable
*
Lo
=
Var
->
getLo
();
Variable
*
Hi
=
Var
->
getHi
();
if
(
Lo
)
{
assert
(
Hi
);
return
;
}
assert
(
Hi
==
nullptr
);
Lo
=
Func
->
makeVariable
(
IceType_i32
);
Hi
=
Func
->
makeVariable
(
IceType_i32
);
if
(
BuildDefs
::
dump
())
{
Lo
->
setName
(
Func
,
Var
->
getName
(
Func
)
+
"__lo"
);
Hi
->
setName
(
Func
,
Var
->
getName
(
Func
)
+
"__hi"
);
}
Var
->
setLoHi
(
Lo
,
Hi
);
if
(
Var
->
getIsArg
())
{
Lo
->
setIsArg
();
Hi
->
setIsArg
();
}
}
Operand
*
TargetARM32
::
loOperand
(
Operand
*
Operand
)
{
Operand
*
TargetARM32
::
loOperand
(
Operand
*
Operand
)
{
assert
(
Operand
->
getType
()
==
IceType_i64
);
assert
(
Operand
->
getType
()
==
IceType_i64
);
if
(
Operand
->
getType
()
!=
IceType_i64
)
if
(
Operand
->
getType
()
!=
IceType_i64
)
return
Operand
;
return
Operand
;
if
(
auto
*
Var
=
llvm
::
dyn_cast
<
Variable
>
(
Operand
))
{
if
(
auto
*
Var64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Operand
))
split64
(
Var
);
return
Var64On32
->
getLo
();
return
Var
->
getLo
();
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
}
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
return
Ctx
->
getConstantInt32
(
static_cast
<
uint32_t
>
(
Const
->
getValue
()));
return
Ctx
->
getConstantInt32
(
static_cast
<
uint32_t
>
(
Const
->
getValue
()));
}
if
(
auto
*
Mem
=
llvm
::
dyn_cast
<
OperandARM32Mem
>
(
Operand
))
{
if
(
auto
*
Mem
=
llvm
::
dyn_cast
<
OperandARM32Mem
>
(
Operand
))
{
// Conservatively disallow memory operands with side-effects (pre/post
// Conservatively disallow memory operands with side-effects (pre/post
// increment) in case of duplication.
// increment) in case of duplication.
...
@@ -1107,10 +1074,8 @@ Operand *TargetARM32::hiOperand(Operand *Operand) {
...
@@ -1107,10 +1074,8 @@ Operand *TargetARM32::hiOperand(Operand *Operand) {
assert
(
Operand
->
getType
()
==
IceType_i64
);
assert
(
Operand
->
getType
()
==
IceType_i64
);
if
(
Operand
->
getType
()
!=
IceType_i64
)
if
(
Operand
->
getType
()
!=
IceType_i64
)
return
Operand
;
return
Operand
;
if
(
auto
*
Var
=
llvm
::
dyn_cast
<
Variable
>
(
Operand
))
{
if
(
auto
*
Var64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Operand
))
split64
(
Var
);
return
Var64On32
->
getHi
();
return
Var
->
getHi
();
}
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
return
Ctx
->
getConstantInt32
(
return
Ctx
->
getConstantInt32
(
static_cast
<
uint32_t
>
(
Const
->
getValue
()
>>
32
));
static_cast
<
uint32_t
>
(
Const
->
getValue
()
>>
32
));
...
@@ -1935,10 +1900,9 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
...
@@ -1935,10 +1900,9 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
// Assign the result of the call to Dest.
// Assign the result of the call to Dest.
if
(
ReturnReg
)
{
if
(
ReturnReg
)
{
if
(
ReturnRegHi
)
{
if
(
ReturnRegHi
)
{
assert
(
Dest
->
getType
()
==
IceType_i64
);
auto
*
Dest64On32
=
llvm
::
cast
<
Variable64On32
>
(
Dest
);
split64
(
Dest
);
Variable
*
DestLo
=
Dest64On32
->
getLo
();
Variable
*
DestLo
=
Dest
->
getLo
();
Variable
*
DestHi
=
Dest64On32
->
getHi
();
Variable
*
DestHi
=
Dest
->
getHi
();
_mov
(
DestLo
,
ReturnReg
);
_mov
(
DestLo
,
ReturnReg
);
_mov
(
DestHi
,
ReturnRegHi
);
_mov
(
DestHi
,
ReturnRegHi
);
}
else
{
}
else
{
...
@@ -2103,10 +2067,10 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
...
@@ -2103,10 +2067,10 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
if
(
isVectorType
(
Dest
->
getType
()))
{
if
(
isVectorType
(
Dest
->
getType
()))
{
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
break
;
break
;
}
else
if
(
Dest
->
getType
()
==
IceType_i64
)
{
}
split64
(
Dest
);
if
(
auto
*
Dest64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Dest
))
{
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
Dest
->
getLo
()));
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
Dest
64On32
->
getLo
()));
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
Dest
->
getHi
()));
Context
.
insert
(
InstFakeDef
::
create
(
Func
,
Dest
64On32
->
getHi
()));
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
UnimplementedError
(
Func
->
getContext
()
->
getFlags
());
break
;
break
;
}
}
...
@@ -2213,10 +2177,10 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
...
@@ -2213,10 +2177,10 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
Variable
*
T0
=
makeReg
(
IceType_i32
);
Variable
*
T0
=
makeReg
(
IceType_i32
);
Variable
*
T1
=
makeReg
(
IceType_i32
);
Variable
*
T1
=
makeReg
(
IceType_i32
);
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
Variable
*
Src0R
=
legalizeToReg
(
Src0
);
split64
(
Dest
);
_vmov
(
InstARM32Vmov
::
RegisterPair
(
T0
,
T1
),
Src0R
);
_vmov
(
InstARM32Vmov
::
RegisterPair
(
T0
,
T1
),
Src0R
);
lowerAssign
(
InstAssign
::
create
(
Func
,
Dest
->
getLo
(),
T0
));
auto
*
Dest64On32
=
llvm
::
cast
<
Variable64On32
>
(
Dest
);
lowerAssign
(
InstAssign
::
create
(
Func
,
Dest
->
getHi
(),
T1
));
lowerAssign
(
InstAssign
::
create
(
Func
,
Dest64On32
->
getLo
(),
T0
));
lowerAssign
(
InstAssign
::
create
(
Func
,
Dest64On32
->
getHi
(),
T1
));
break
;
break
;
}
}
case
IceType_f64
:
{
case
IceType_f64
:
{
...
...
src/IceTargetLoweringARM32.h
View file @
6d47bcdc
...
@@ -85,6 +85,10 @@ public:
...
@@ -85,6 +85,10 @@ public:
return
(
typeWidthInBytes
(
Ty
)
+
3
)
&
~
3
;
return
(
typeWidthInBytes
(
Ty
)
+
3
)
&
~
3
;
}
}
bool
shouldSplitToVariable64On32
(
Type
Ty
)
const
override
{
return
Ty
==
IceType_i64
;
}
// TODO(ascull): what size is best for ARM?
// TODO(ascull): what size is best for ARM?
SizeT
getMinJumpTableSize
()
const
override
{
return
3
;
}
SizeT
getMinJumpTableSize
()
const
override
{
return
3
;
}
void
emitJumpTable
(
const
Cfg
*
Func
,
void
emitJumpTable
(
const
Cfg
*
Func
,
...
@@ -103,9 +107,6 @@ public:
...
@@ -103,9 +107,6 @@ public:
void
addProlog
(
CfgNode
*
Node
)
override
;
void
addProlog
(
CfgNode
*
Node
)
override
;
void
addEpilog
(
CfgNode
*
Node
)
override
;
void
addEpilog
(
CfgNode
*
Node
)
override
;
/// Ensure that a 64-bit Variable has been split into 2 32-bit Variables,
/// creating them if necessary. This is needed for all I64 operations.
void
split64
(
Variable
*
Var
);
Operand
*
loOperand
(
Operand
*
Operand
);
Operand
*
loOperand
(
Operand
*
Operand
);
Operand
*
hiOperand
(
Operand
*
Operand
);
Operand
*
hiOperand
(
Operand
*
Operand
);
void
finishArgumentLowering
(
Variable
*
Arg
,
Variable
*
FramePtr
,
void
finishArgumentLowering
(
Variable
*
Arg
,
Variable
*
FramePtr
,
...
...
src/IceTargetLoweringMIPS32.h
View file @
6d47bcdc
...
@@ -57,6 +57,10 @@ public:
...
@@ -57,6 +57,10 @@ public:
return
(
typeWidthInBytes
(
Ty
)
+
3
)
&
~
3
;
return
(
typeWidthInBytes
(
Ty
)
+
3
)
&
~
3
;
}
}
bool
shouldSplitToVariable64On32
(
Type
Ty
)
const
override
{
return
Ty
==
IceType_i64
;
}
// TODO(ascull): what is the best size of MIPS?
// TODO(ascull): what is the best size of MIPS?
SizeT
getMinJumpTableSize
()
const
override
{
return
3
;
}
SizeT
getMinJumpTableSize
()
const
override
{
return
3
;
}
void
emitJumpTable
(
const
Cfg
*
Func
,
void
emitJumpTable
(
const
Cfg
*
Func
,
...
...
src/IceTargetLoweringX8632.cpp
View file @
6d47bcdc
...
@@ -263,10 +263,9 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
...
@@ -263,10 +263,9 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
// Assign the result of the call to Dest.
// Assign the result of the call to Dest.
if
(
ReturnReg
)
{
if
(
ReturnReg
)
{
if
(
ReturnRegHi
)
{
if
(
ReturnRegHi
)
{
assert
(
Dest
->
getType
()
==
IceType_i64
);
auto
*
Dest64On32
=
llvm
::
cast
<
Variable64On32
>
(
Dest
);
split64
(
Dest
);
Variable
*
DestLo
=
Dest64On32
->
getLo
();
Variable
*
DestLo
=
Dest
->
getLo
();
Variable
*
DestHi
=
Dest64On32
->
getHi
();
Variable
*
DestHi
=
Dest
->
getHi
();
_mov
(
DestLo
,
ReturnReg
);
_mov
(
DestLo
,
ReturnReg
);
_mov
(
DestHi
,
ReturnRegHi
);
_mov
(
DestHi
,
ReturnRegHi
);
}
else
{
}
else
{
...
...
src/IceTargetLoweringX86Base.h
View file @
6d47bcdc
...
@@ -92,6 +92,10 @@ public:
...
@@ -92,6 +92,10 @@ public:
return
Utils
::
applyAlignment
(
typeWidthInBytes
(
Ty
),
WordSizeInBytes
);
return
Utils
::
applyAlignment
(
typeWidthInBytes
(
Ty
),
WordSizeInBytes
);
}
}
bool
shouldSplitToVariable64On32
(
Type
Ty
)
const
override
{
return
Traits
::
Is64Bit
?
false
:
Ty
==
IceType_i64
;
}
SizeT
getMinJumpTableSize
()
const
override
{
return
4
;
}
SizeT
getMinJumpTableSize
()
const
override
{
return
4
;
}
void
emitVariable
(
const
Variable
*
Var
)
const
override
;
void
emitVariable
(
const
Variable
*
Var
)
const
override
;
...
@@ -104,21 +108,6 @@ public:
...
@@ -104,21 +108,6 @@ public:
void
emit
(
const
ConstantDouble
*
C
)
const
final
;
void
emit
(
const
ConstantDouble
*
C
)
const
final
;
void
initNodeForLowering
(
CfgNode
*
Node
)
override
;
void
initNodeForLowering
(
CfgNode
*
Node
)
override
;
/// x86-32: Ensure that a 64-bit Variable has been split into 2 32-bit
/// Variables, creating them if necessary. This is needed for all I64
/// operations, and it is needed for pushing F64 arguments for function calls
/// using the 32-bit push instruction (though the latter could be done by
/// directly writing to the stack).
///
/// x86-64: Complains loudly if invoked because the cpu can handle 64-bit
/// types natively.
template
<
typename
T
=
Traits
>
typename
std
::
enable_if
<!
T
::
Is64Bit
,
void
>::
type
split64
(
Variable
*
Var
);
template
<
typename
T
=
Traits
>
typename
std
::
enable_if
<
T
::
Is64Bit
,
void
>::
type
split64
(
Variable
*
)
{
llvm
::
report_fatal_error
(
"Hey, yo! This is x86-64. Watcha doin'? (split64)"
);
}
template
<
typename
T
=
Traits
>
template
<
typename
T
=
Traits
>
typename
std
::
enable_if
<!
T
::
Is64Bit
,
Operand
>::
type
*
typename
std
::
enable_if
<!
T
::
Is64Bit
,
Operand
>::
type
*
...
...
src/IceTargetLoweringX86BaseImpl.h
View file @
6d47bcdc
...
@@ -792,16 +792,16 @@ void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
...
@@ -792,16 +792,16 @@ void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
Variable
*
FramePtr
,
Variable
*
FramePtr
,
size_t
BasicFrameOffset
,
size_t
BasicFrameOffset
,
size_t
&
InArgsSizeBytes
)
{
size_t
&
InArgsSizeBytes
)
{
Variable
*
Lo
=
Arg
->
getLo
();
if
(
!
Traits
::
Is64Bit
)
{
Variable
*
Hi
=
Arg
->
getHi
();
if
(
auto
*
Arg64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Arg
))
{
Type
Ty
=
Arg
->
getType
();
Variable
*
Lo
=
Arg64On32
->
getLo
();
if
(
!
Traits
::
Is64Bit
&&
Lo
&&
Hi
&&
Ty
==
IceType_i64
)
{
Variable
*
Hi
=
Arg64On32
->
getHi
();
assert
(
Lo
->
getType
()
!=
IceType_i64
);
// don't want infinite recursion
finishArgumentLowering
(
Lo
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
assert
(
Hi
->
getType
()
!=
IceType_i64
);
// don't want infinite recursion
finishArgumentLowering
(
Hi
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
finishArgumentLowering
(
Lo
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
return
;
finishArgumentLowering
(
Hi
,
FramePtr
,
BasicFrameOffset
,
InArgsSizeBytes
);
}
return
;
}
}
Type
Ty
=
Arg
->
getType
();
if
(
isVectorType
(
Ty
))
{
if
(
isVectorType
(
Ty
))
{
InArgsSizeBytes
=
Traits
::
applyStackAlignment
(
InArgsSizeBytes
);
InArgsSizeBytes
=
Traits
::
applyStackAlignment
(
InArgsSizeBytes
);
}
}
...
@@ -829,49 +829,14 @@ template <class Machine> Type TargetX86Base<Machine>::stackSlotType() {
...
@@ -829,49 +829,14 @@ template <class Machine> Type TargetX86Base<Machine>::stackSlotType() {
template
<
class
Machine
>
template
<
class
Machine
>
template
<
typename
T
>
template
<
typename
T
>
typename
std
::
enable_if
<!
T
::
Is64Bit
,
void
>::
type
TargetX86Base
<
Machine
>::
split64
(
Variable
*
Var
)
{
switch
(
Var
->
getType
())
{
default
:
return
;
case
IceType_i64
:
// TODO: Only consider F64 if we need to push each half when passing as an
// argument to a function call. Note that each half is still typed as I32.
case
IceType_f64
:
break
;
}
Variable
*
Lo
=
Var
->
getLo
();
Variable
*
Hi
=
Var
->
getHi
();
if
(
Lo
)
{
assert
(
Hi
);
return
;
}
assert
(
Hi
==
nullptr
);
Lo
=
Func
->
makeVariable
(
IceType_i32
);
Hi
=
Func
->
makeVariable
(
IceType_i32
);
if
(
BuildDefs
::
dump
())
{
Lo
->
setName
(
Func
,
Var
->
getName
(
Func
)
+
"__lo"
);
Hi
->
setName
(
Func
,
Var
->
getName
(
Func
)
+
"__hi"
);
}
Var
->
setLoHi
(
Lo
,
Hi
);
if
(
Var
->
getIsArg
())
{
Lo
->
setIsArg
();
Hi
->
setIsArg
();
}
}
template
<
class
Machine
>
template
<
typename
T
>
typename
std
::
enable_if
<!
T
::
Is64Bit
,
Operand
>::
type
*
typename
std
::
enable_if
<!
T
::
Is64Bit
,
Operand
>::
type
*
TargetX86Base
<
Machine
>::
loOperand
(
Operand
*
Operand
)
{
TargetX86Base
<
Machine
>::
loOperand
(
Operand
*
Operand
)
{
assert
(
Operand
->
getType
()
==
IceType_i64
||
assert
(
Operand
->
getType
()
==
IceType_i64
||
Operand
->
getType
()
==
IceType_f64
);
Operand
->
getType
()
==
IceType_f64
);
if
(
Operand
->
getType
()
!=
IceType_i64
&&
Operand
->
getType
()
!=
IceType_f64
)
if
(
Operand
->
getType
()
!=
IceType_i64
&&
Operand
->
getType
()
!=
IceType_f64
)
return
Operand
;
return
Operand
;
if
(
auto
*
Var
=
llvm
::
dyn_cast
<
Variable
>
(
Operand
))
{
if
(
auto
*
Var64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Operand
))
split64
(
Var
);
return
Var64On32
->
getLo
();
return
Var
->
getLo
();
}
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
auto
*
ConstInt
=
llvm
::
dyn_cast
<
ConstantInteger32
>
(
auto
*
ConstInt
=
llvm
::
dyn_cast
<
ConstantInteger32
>
(
Ctx
->
getConstantInt32
(
static_cast
<
int32_t
>
(
Const
->
getValue
())));
Ctx
->
getConstantInt32
(
static_cast
<
int32_t
>
(
Const
->
getValue
())));
...
@@ -899,10 +864,8 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
...
@@ -899,10 +864,8 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
Operand
->
getType
()
==
IceType_f64
);
Operand
->
getType
()
==
IceType_f64
);
if
(
Operand
->
getType
()
!=
IceType_i64
&&
Operand
->
getType
()
!=
IceType_f64
)
if
(
Operand
->
getType
()
!=
IceType_i64
&&
Operand
->
getType
()
!=
IceType_f64
)
return
Operand
;
return
Operand
;
if
(
auto
*
Var
=
llvm
::
dyn_cast
<
Variable
>
(
Operand
))
{
if
(
auto
*
Var64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Operand
))
split64
(
Var
);
return
Var64On32
->
getHi
();
return
Var
->
getHi
();
}
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
if
(
auto
*
Const
=
llvm
::
dyn_cast
<
ConstantInteger64
>
(
Operand
))
{
auto
*
ConstInt
=
llvm
::
dyn_cast
<
ConstantInteger32
>
(
auto
*
ConstInt
=
llvm
::
dyn_cast
<
ConstantInteger32
>
(
Ctx
->
getConstantInt32
(
static_cast
<
int32_t
>
(
Const
->
getValue
()
>>
32
)));
Ctx
->
getConstantInt32
(
static_cast
<
int32_t
>
(
Const
->
getValue
()
>>
32
)));
...
@@ -2006,12 +1969,6 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
...
@@ -2006,12 +1969,6 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
_cvt
(
T
,
Src0RM
,
Traits
::
Insts
::
Cvt
::
Tps2dq
);
_cvt
(
T
,
Src0RM
,
Traits
::
Insts
::
Cvt
::
Tps2dq
);
_movp
(
Dest
,
T
);
_movp
(
Dest
,
T
);
}
else
if
(
!
Traits
::
Is64Bit
&&
Dest
->
getType
()
==
IceType_i64
)
{
}
else
if
(
!
Traits
::
Is64Bit
&&
Dest
->
getType
()
==
IceType_i64
)
{
// Use a helper for converting floating-point values to 64-bit integers.
// SSE2 appears to have no way to convert from xmm registers to something
// like the edx:eax register pair, and gcc and clang both want to use x87
// instructions complete with temporary manipulation of the status word.
// This helper is not needed for x86-64.
split64
(
Dest
);
const
SizeT
MaxSrcs
=
1
;
const
SizeT
MaxSrcs
=
1
;
Type
SrcType
=
Inst
->
getSrc
(
0
)
->
getType
();
Type
SrcType
=
Inst
->
getSrc
(
0
)
->
getType
();
InstCall
*
Call
=
InstCall
*
Call
=
...
@@ -2051,8 +2008,6 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
...
@@ -2051,8 +2008,6 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
}
else
if
(
Dest
->
getType
()
==
IceType_i64
||
}
else
if
(
Dest
->
getType
()
==
IceType_i64
||
(
!
Traits
::
Is64Bit
&&
Dest
->
getType
()
==
IceType_i32
))
{
(
!
Traits
::
Is64Bit
&&
Dest
->
getType
()
==
IceType_i32
))
{
// Use a helper for both x86-32 and x86-64.
// Use a helper for both x86-32 and x86-64.
if
(
!
Traits
::
Is64Bit
)
split64
(
Dest
);
const
SizeT
MaxSrcs
=
1
;
const
SizeT
MaxSrcs
=
1
;
Type
DestType
=
Dest
->
getType
();
Type
DestType
=
Dest
->
getType
();
Type
SrcType
=
Inst
->
getSrc
(
0
)
->
getType
();
Type
SrcType
=
Inst
->
getSrc
(
0
)
->
getType
();
...
@@ -2901,23 +2856,25 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
...
@@ -2901,23 +2856,25 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
return
;
return
;
}
}
Variable
*
Dest
=
Instr
->
getDest
();
Variable
*
Dest
=
Instr
->
getDest
();
if
(
!
Traits
::
Is64Bit
&&
Dest
->
getType
()
==
IceType_i64
)
{
if
(
!
Traits
::
Is64Bit
)
{
// Follow what GCC does and use a movq instead of what lowerLoad()
if
(
auto
*
Dest64On32
=
llvm
::
dyn_cast
<
Variable64On32
>
(
Dest
))
{
// normally does (split the load into two). Thus, this skips
// Follow what GCC does and use a movq instead of what lowerLoad()
// load/arithmetic op folding. Load/arithmetic folding can't happen
// normally does (split the load into two). Thus, this skips
// anyway, since this is x86-32 and integer arithmetic only happens on
// load/arithmetic op folding. Load/arithmetic folding can't happen
// 32-bit quantities.
// anyway, since this is x86-32 and integer arithmetic only happens on
Variable
*
T
=
makeReg
(
IceType_f64
);
// 32-bit quantities.
typename
Traits
::
X86OperandMem
*
Addr
=
Variable
*
T
=
makeReg
(
IceType_f64
);
formMemoryOperand
(
Instr
->
getArg
(
0
),
IceType_f64
);
typename
Traits
::
X86OperandMem
*
Addr
=
_movq
(
T
,
Addr
);
formMemoryOperand
(
Instr
->
getArg
(
0
),
IceType_f64
);
// Then cast the bits back out of the XMM register to the i64 Dest.
_movq
(
T
,
Addr
);
InstCast
*
Cast
=
InstCast
::
create
(
Func
,
InstCast
::
Bitcast
,
Dest
,
T
);
// Then cast the bits back out of the XMM register to the i64 Dest.
lowerCast
(
Cast
);
InstCast
*
Cast
=
InstCast
::
create
(
Func
,
InstCast
::
Bitcast
,
Dest
,
T
);
// Make sure that the atomic load isn't elided when unused.
lowerCast
(
Cast
);
Context
.
insert
(
InstFakeUse
::
create
(
Func
,
Dest
->
getLo
()));
// Make sure that the atomic load isn't elided when unused.
Context
.
insert
(
InstFakeUse
::
create
(
Func
,
Dest
->
getHi
()));
Context
.
insert
(
InstFakeUse
::
create
(
Func
,
Dest64On32
->
getLo
()));
return
;
Context
.
insert
(
InstFakeUse
::
create
(
Func
,
Dest64On32
->
getHi
()));
return
;
}
}
}
InstLoad
*
Load
=
InstLoad
::
create
(
Func
,
Dest
,
Instr
->
getArg
(
0
));
InstLoad
*
Load
=
InstLoad
::
create
(
Func
,
Dest
,
Instr
->
getArg
(
0
));
lowerLoad
(
Load
);
lowerLoad
(
Load
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment